Conversation
`loongforge/` now separates the two training backends instead of sharing
modules that only one of them needs.
- `engine/{common,mcore,native}/` owns each backend's parser, trainers,
registries, distributed strategies, and checkpoint flow; `contracts/`,
`distributed/`, `optim/`, and `checkpoint/` keep only what both engines use.
- `loongforge/train.py` and `loongforge/embodied/train.py` collapse into one
entry point (`python -m loongforge train --engine {mcore,native}`, also the
`LoongForge` console script), driven by `configs/recipes/` and
`configs/engines/`; the launch scripts, examples, tests, and docs follow it.
- Model registries split per engine (`models/mcore_registry.py`,
`models/native_registry.py`), and MCore's Megatron-backed globals move to
`engine/mcore/global_vars.py`, so importing `loongforge.utils` no longer
drags Megatron into Native runs. A regression test pins that boundary.
- `tools/` exists only at the repository root, and package-internal pytest
files move to `tests/native/unit/` so they stop shipping in the wheel.
Downstream launch scripts have to switch from the old file paths to
`-m loongforge`; every in-repo script and example is already updated here.
dyedd
marked this pull request as draft
September 16, 2026 06:31
…mcore
The engine axis now reads as `mcore` (Megatron-backed) versus `torch`
(standalone) in package paths, CLI values, suite names, and CI wiring, so a
name says which training loop it refers to instead of which model family was
tested first.
- `loongforge/engine/native/` and `loongforge/checkpoint/native/` move to
`engine/torch/` and `checkpoint/torch/`; `models/native_registry.py`,
`NativeCheckpointMetadata`, and the `NATIVE_*` symbols and env vars follow.
- `--engine native` becomes `--engine torch`, and
`configs/engines/native.yaml` becomes `torch.yaml`; every in-repo launch
script, example, test, and doc is updated here.
- `tests/llm_vlm/` becomes `tests/mcore/` and the suite flag becomes
`--suite {mcore,torch}`; `ci_command.py`, the workflows, the self-runner
scripts, artifact names, `CI_ENABLE_MCORE`, and
`LOONGFORGE_BASELINE_MCORE` follow.
- `docs/{source,source_zh}/native_tutorial/` becomes `torch_tutorial/`,
including the readthedocs links in both READMEs.
- Drop `tests/torch/__init__.py`: with `tests/` on `sys.path`, pytest's
prepend import mode resolved `import torch` to that test package.
- The torch suite's data root default moves from
`/workspace/loongforge_native_ci` to `/workspace/loongforge_torch_ci` in
`config/env.sh`, `cli.py`, and the example scripts, matching the mcore
suite's `/workspace/loongforge_ci`.
Batch 1 of the structure cleanup: a package per type is not a boundary, so
`contracts/` and `distributed/` become modules and the two leaf helpers join
the modules they belong to.
- `contracts/{model,data,training,checkpoint}.py` and the re-exporting
`__init__.py` collapse into `contracts.py`; the Cosmos/OpenMDW notice moves
onto `Cosmos3Batch`, which is the only borrowed code there.
- `distributed/{context,collectives}.py` collapse into `distributed.py`, with
the engine boundary (DDP/FSDP vs TP/PP/CP/VPP) stated in the docstring.
- `engine/common/__init__.py` becomes `engine/dispatch.py`: it dispatches a
`TrainSpec`, and a package holding one `__init__.py` hid that.
- `utils/xpu_init.py` becomes `_init_xpu_plugin()` in `utils/utils.py`, and
`tokenizer/defaults.py` joins `tokenizer/tokenizer.py`; both keep the same
import-time behaviour.
- `models/dtype.py` stays as it is: the only merge targets would pull
`megatron.core` into Torch-side imports or make models depend on the
top-level runtime package.
README.md, README_zh.md, CLAUDE.md, and the structure doc follow the new paths.
`MCORE_CONFIGS` stored `{"config_path": ..., "config_name": ...}` dicts that
`get_model_spec()` reassembled into a `ModelSpec` with its own copy of the
config root, while `TORCH_CONFIGS` already held `ModelSpec` entries built by
`_torch()`. Both registries now go through `_mcore()` / `_torch()` and resolve
their YAML against the single `_CONFIGS_DIR`, so `get_model_spec()` is a
lookup plus the engine and existence checks.
All 112 entries resolve to the same engine, config file, and config classes as
before, verified by comparing `get_model_spec()` output against the previous
implementation.
Seventeen directories under `loongforge/` were imported as packages but had no `__init__.py`, so they resolved as namespace packages: two same-named directories on `sys.path` would merge silently instead of one winning, and the layout disagreed with the rest of the tree. Each now carries the license header and a one-line docstring; no re-exports are added, so no module gains side effects. `loongforge/models/vla/xvla/tests/` is included for consistency even though package-local test code is still a candidate to move under `tests/`.
Batch 3 of the structure cleanup: each `models/vision/<tower>/` repeated the tower name in every file name, so the same four roles were spelled eight different ways. - A tower now names its modules by role -- `config.py`, `layer_spec.py`, `vision_model.py`, `adapter.py`, plus `attention.py`, `transformer_layer.py`, `image_preprocess.py`, `merger.py`, `rope_utils.py`, and `patch_merger_adapter.py` where the tower needs them. The tower name lives in the directory, not in each file. - `base_vision_models/` held a single module, so `BaseVisionModel` moves up to `models/vision/base_vision_model.py`, beside the shared ViT block. - The `model_spec:` entries in `configs/models/` and the two FP8-for-VLM guides follow the new module paths. Class and function names do not change, so the rest of the configs stays put. Checked by resolving every dotted `loongforge.*` reference in the repository against the file tree and by parsing every import under `loongforge/`; no module was imported at runtime (a CPU-only box has no torch).
Tests are not supposed to ship in `loongforge/` -- that is why the other package-internal units already live under `tests/` -- and the XVLA attention test was the last one left behind. - `models/vla/xvla/tests/test_attention_forward.py` and its runner move to `tests/torch/unit/`, next to the other Torch units. - The runner derives the repo root from its own location instead of defaulting to `/workspace/LoongForge`, so it works from any checkout. - `tests/torch/README.md` lists `unit/` in the directory tree; the tree had never mentioned it. The test still skips itself when CUDA is absent, and nothing else in the repo referenced the old path.
`f95a6eb` moved the multimodal dataloader into `engine/mcore/` and the VLM data pipeline under `datasets/`, but two references kept the old shape. - `engine/mcore/dataloader_provider.py` imported `print_error_handler` from `.base.task_encoder`, which does not resolve under `engine/mcore/`; the function lives in `loongforge.datasets.multimodal.base.task_encoder`. - `models/vla/xvla/xvla_processor.py` described the training transforms as `loongforge.datasets.transforms.xvla.xvla_transform`, missing the `robotics` segment. Found by checking every dotted `loongforge.*` reference and every import in the repository against the file tree.
`evaluation/orchestrator/compare_repro.py` was a twelve-line `main()` wrapper around `evaluation/metrics/repro_compare.py`, with no caller in the code, the docs, or the scripts. The underlying module already runs on its own as `python -m loongforge.evaluation.metrics.repro_compare`.
`models/llm/qwen3/qwen3_config.py` repeated the family name the directory already carries. The convention the vision towers adopted in the previous batch now covers every model directory: the path names the family, the module names the role (`config.py`, `model.py`, `layer_spec.py`, `attention.py`, `provider.py`). - 124 renames: the 8 vision tower directories and their 41 modules (`moon_vision_models/` -> `moon/`, `qwen3_5_vision_models/` -> `qwen3_5_vl/`), plus 83 LLM, diffusion, vision, VLA, and world modules (`deepseek_model.py` -> `model.py`, `kimi_k3_moe.py` -> `moe.py`, `wan_flow_match.py` -> `flow_match.py`, `dreamzero_provider.py` -> `provider.py`). - `world/cosmos3/qwen3_vl.py` becomes `modeling_qwen3_vl.py` because it is a port of the HF file. Every other HF port (`modeling_*`, `model_configuration_*`, `configuration_*`) keeps its upstream name, and the rule is now written down in CLAUDE.md and both READMEs. - 152 dotted `loongforge.models.*` references and 104 relative imports are updated, together with 67 `model_spec` entries in 37 `configs/` files and 11 modules under `engine/`, `datasets/`, `tests/`, and `tools/`. Two DreamZero comments pointed at the old `wan_flow_match.py` path and follow. Verified statically: every `loongforge.*` import in the tree resolves on disk, `compileall` is clean, the 61 CI-helper pytest cases pass, and ruff reports the same per-rule counts as `ed4ed97`. No GPU run: only module paths moved.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
loongforge/now separates the two training backends instead of sharing modules that only one of them needs.engine/{common,mcore,native}/owns each backend's parser, trainers, registries, distributed strategies, and checkpoint flow;contracts/,distributed/,optim/, andcheckpoint/keep only what both engines use.loongforge/train.pyandloongforge/embodied/train.pycollapse into one entry point (python -m loongforge train --engine {mcore,native}, also theLoongForgeconsole script), driven byconfigs/recipes/andconfigs/engines/; the launch scripts, examples, tests, and docs follow it.models/mcore_registry.py,models/native_registry.py), and MCore's Megatron-backed globals move toengine/mcore/global_vars.py, so importingloongforge.utilsno longer drags Megatron into Native runs. A regression test pins that boundary.tools/exists only at the repository root, and package-internal pytest files move totests/native/unit/so they stop shipping in the wheel.Downstream launch scripts have to switch from the old file paths to
-m loongforge; every in-repo script and example is already updated here.Change Summary
Validation
CI, GPU, and Image Impact
llm_vlm/embodied.Reviewer Notes
Describe any known risks, rollout considerations, or follow-up work.