From 9927fbe14d5123a9d0187083ff5f61f4264ba99f Mon Sep 17 00:00:00 2001 From: CanGeng <2441506707@qq.com> Date: Sat, 27 Jun 2026 09:38:25 +0800 Subject: [PATCH 1/2] chore(examples): merge recipes/ into examples/references/ (relocation, behavior-preserving) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unify the two split entry-point trees (root recipes/*.yaml + examples/*.py) under examples/references/: YAML recipes → examples/references/recipes/, programmatic API scripts → examples/references/. Keeps the "recipe" concept word (CLI/registry/test-group names unchanged); only file paths move. - git mv: 29 recipes + 23 example scripts + README (history preserved). - Path refs updated: recipes/ → examples/references/recipes/ across scripts, docs (concepts/extending/operations), production docstrings + CLI --help epilogs, scripts/rt.sh, tests (string + Path-segment forms); shared modules examples/{lab_components,vision_components,online_distill} → references/... in user_modules: and the one dotted test import. - Untouched: docs/changelog/** (point-in-time history), the OOM-report test's arbitrary fake config path. Shared lab_components.py (used by 5 recipes) sits flat in references/ — why a per-example subdir layout was rejected (it can't live in 5 subdirs). Verified: pytest 4491 passed/0 failed, ruff clean, mypy 575 files 0 errors, CLI print-config on the new canonical path, zero residual recipes/ refs. CanGeng --- README.md | 6 ++-- README.zh-CN.md | 6 ++-- docs/concepts/training.md | 2 +- docs/concepts/training.zh-CN.md | 2 +- docs/extending/architectures.md | 12 +++---- docs/extending/architectures.zh-CN.md | 12 +++---- docs/extending/recipes.md | 4 +-- docs/extending/recipes.zh-CN.md | 4 +-- docs/operations/distributed.md | 2 +- docs/operations/distributed.zh-CN.md | 2 +- examples/README.md | 35 +++++++------------ examples/references/README.md | 30 ++++++++++++++++ examples/{ => references}/diffusion_eps.py | 4 +-- examples/{ => references}/dpo_offline.py | 4 +-- examples/{ => references}/ff_demo.py | 4 +-- examples/{ => references}/fork_resume.py | 8 ++--- examples/{ => references}/grpo.py | 4 +-- examples/{ => references}/image_cls.py | 4 +-- examples/{ => references}/jepa.py | 4 +-- examples/{ => references}/lab_components.py | 0 examples/{ => references}/mezo_sft.py | 4 +-- .../{ => references}/offload_fullparam.py | 4 +-- examples/{ => references}/online_distill.py | 2 +- examples/{ => references}/pcn_demo.py | 4 +-- examples/{ => references}/ppo_online.py | 4 +-- examples/{ => references}/pretrain_causal.py | 4 +-- examples/{ => references}/pretrain_rwkv.py | 4 +-- examples/{ => references}/produce_teacher.py | 4 +-- examples/{ => references}/qlora.py | 4 +-- .../references/recipes}/ddp.yaml | 2 +- .../references/recipes}/diffusion_eps.yaml | 4 +-- .../references/recipes}/dpo_offline.yaml | 6 ++-- .../references/recipes}/ff_demo.yaml | 4 +-- .../references/recipes}/fork_resume.yaml | 4 +-- .../references/recipes}/fsdp.yaml | 2 +- .../references/recipes}/grpo.yaml | 2 +- .../references/recipes}/image_cls.yaml | 4 +-- .../references/recipes}/jepa.yaml | 4 +-- .../references/recipes}/mezo_sft.yaml | 4 +-- .../references/recipes}/nano_fsdp.yaml | 2 +- .../references/recipes}/nano_model.yaml | 2 +- .../references/recipes}/nano_zero2.yaml | 2 +- .../recipes}/offload_fullparam.yaml | 6 ++-- .../recipes}/online_distill_demo.yaml | 8 ++--- .../references/recipes}/pcn_demo.yaml | 4 +-- .../references/recipes}/ppo_online.yaml | 2 +- .../references/recipes}/pretrain_causal.yaml | 0 .../references/recipes}/pretrain_rwkv.yaml | 2 +- .../references/recipes}/produce_teacher.yaml | 4 +-- .../references/recipes}/qlora.yaml | 4 +-- .../references/recipes}/sft_chat.yaml | 2 +- .../references/recipes}/sft_chat_hf.yaml | 0 .../references/recipes}/student_kd.yaml | 4 +-- .../references/recipes}/sweep_demo.yaml | 2 +- .../references/recipes}/sweep_lr.yaml | 4 +-- .../references/recipes}/sweep_r15.yaml | 2 +- .../references/recipes}/vlm_sft.yaml | 0 .../references/recipes}/zero2.yaml | 4 +-- examples/{ => references}/sft_chat.py | 4 +-- examples/{ => references}/sft_chat_hf.py | 4 +-- examples/{ => references}/student_kd.py | 4 +-- examples/{ => references}/sweep_demo.py | 6 ++-- .../{ => references}/vision_components.py | 0 examples/{ => references}/vlm_sft.py | 4 +-- .../builtin_plugins/data/processors/image.py | 2 +- .../builtin_plugins/data/processors/text.py | 2 +- lighttrain/builtin_plugins/losses/distill.py | 2 +- lighttrain/cli/commands/artifacts.py | 4 +-- lighttrain/cli/commands/experiment.py | 4 +-- lighttrain/cli/commands/scaffold.py | 4 +-- lighttrain/lab/fork.py | 2 +- tests/cli/test_app.py | 2 +- tests/cli/test_model_build_paths.py | 4 +-- tests/cli/test_runtime.py | 2 +- tests/cli/test_runtime_cov.py | 4 +-- tests/config/test_all_recipes_loadable.py | 4 +-- tests/config/test_models_set_desugar.py | 2 +- tests/recipes/test_image_cls.py | 2 +- tests/recipes/test_r12.py | 2 +- tests/recipes/test_r13.py | 2 +- tests/recipes/test_r4_r6.py | 2 +- tests/recipes/test_smoke.py | 12 +++---- tests/regression/test_gap_report_fixes.py | 8 ++--- tests/trainers/test_ppo_grpo_wiring.py | 2 +- tests/trainers/test_pretrain.py | 2 +- 85 files changed, 193 insertions(+), 172 deletions(-) create mode 100644 examples/references/README.md rename examples/{ => references}/diffusion_eps.py (69%) rename examples/{ => references}/dpo_offline.py (62%) rename examples/{ => references}/ff_demo.py (74%) rename examples/{ => references}/fork_resume.py (70%) rename examples/{ => references}/grpo.py (64%) rename examples/{ => references}/image_cls.py (80%) rename examples/{ => references}/jepa.py (68%) rename examples/{ => references}/lab_components.py (100%) rename examples/{ => references}/mezo_sft.py (66%) rename examples/{ => references}/offload_fullparam.py (70%) rename examples/{ => references}/online_distill.py (99%) rename examples/{ => references}/pcn_demo.py (72%) rename examples/{ => references}/ppo_online.py (63%) rename examples/{ => references}/pretrain_causal.py (58%) rename examples/{ => references}/pretrain_rwkv.py (71%) rename examples/{ => references}/produce_teacher.py (55%) rename examples/{ => references}/qlora.py (75%) rename {recipes => examples/references/recipes}/ddp.yaml (92%) rename {recipes => examples/references/recipes}/diffusion_eps.yaml (92%) rename {recipes => examples/references/recipes}/dpo_offline.yaml (91%) rename {recipes => examples/references/recipes}/ff_demo.yaml (91%) rename {recipes => examples/references/recipes}/fork_resume.yaml (89%) rename {recipes => examples/references/recipes}/fsdp.yaml (92%) rename {recipes => examples/references/recipes}/grpo.yaml (98%) rename {recipes => examples/references/recipes}/image_cls.yaml (91%) rename {recipes => examples/references/recipes}/jepa.yaml (93%) rename {recipes => examples/references/recipes}/mezo_sft.yaml (91%) rename {recipes => examples/references/recipes}/nano_fsdp.yaml (96%) rename {recipes => examples/references/recipes}/nano_model.yaml (96%) rename {recipes => examples/references/recipes}/nano_zero2.yaml (96%) rename {recipes => examples/references/recipes}/offload_fullparam.yaml (88%) rename {recipes => examples/references/recipes}/online_distill_demo.yaml (88%) rename {recipes => examples/references/recipes}/pcn_demo.yaml (91%) rename {recipes => examples/references/recipes}/ppo_online.yaml (98%) rename {recipes => examples/references/recipes}/pretrain_causal.yaml (100%) rename {recipes => examples/references/recipes}/pretrain_rwkv.yaml (96%) rename {recipes => examples/references/recipes}/produce_teacher.yaml (87%) rename {recipes => examples/references/recipes}/qlora.yaml (90%) rename {recipes => examples/references/recipes}/sft_chat.yaml (95%) rename {recipes => examples/references/recipes}/sft_chat_hf.yaml (100%) rename {recipes => examples/references/recipes}/student_kd.yaml (91%) rename {recipes => examples/references/recipes}/sweep_demo.yaml (91%) rename {recipes => examples/references/recipes}/sweep_lr.yaml (84%) rename {recipes => examples/references/recipes}/sweep_r15.yaml (72%) rename {recipes => examples/references/recipes}/vlm_sft.yaml (100%) rename {recipes => examples/references/recipes}/zero2.yaml (74%) rename examples/{ => references}/sft_chat.py (64%) rename examples/{ => references}/sft_chat_hf.py (65%) rename examples/{ => references}/student_kd.py (66%) rename examples/{ => references}/sweep_demo.py (68%) rename examples/{ => references}/vision_components.py (100%) rename examples/{ => references}/vlm_sft.py (65%) diff --git a/README.md b/README.md index d74cfb8..b2a7020 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,8 @@ and is heavily commented as a living tutorial — uncomment the optional blocks ## Example: train, then branch & resume ```bash -lighttrain train -c recipes/pretrain_causal.yaml -lighttrain fork --from runs/<...>/checkpoints/step_500 -c recipes/finetune.yaml +lighttrain train -c examples/references/recipes/pretrain_causal.yaml +lighttrain fork --from runs/<...>/checkpoints/step_500 -c examples/references/recipes/finetune.yaml lighttrain resume --run runs/<...> ``` @@ -78,7 +78,7 @@ judge: { name: verifier, verify_pattern: "\\d+" } # → reward_fn Multi-model (a frozen teacher + a trainable student) is a named model set; a custom trainer reads `self.models["teacher"]`. A runnable end-to-end template: [examples/online_distill.py](examples/online_distill.py) -(`lighttrain train -c recipes/online_distill_demo.yaml`). +(`lighttrain train -c examples/references/recipes/online_distill_demo.yaml`). → [Training paradigms](docs/concepts/training.md) ## What you get diff --git a/README.zh-CN.md b/README.zh-CN.md index 5191444..481cd08 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -54,8 +54,8 @@ lighttrain train -c cfg.yaml ++trainer.max_steps=50 # 50 步冒烟 ## 示例:训练,然后分叉与恢复 ```bash -lighttrain train -c recipes/pretrain_causal.yaml -lighttrain fork --from runs/<...>/checkpoints/step_500 -c recipes/finetune.yaml +lighttrain train -c examples/references/recipes/pretrain_causal.yaml +lighttrain fork --from runs/<...>/checkpoints/step_500 -c examples/references/recipes/finetune.yaml lighttrain resume --run runs/<...> ``` @@ -72,7 +72,7 @@ judge: { name: verifier, verify_pattern: "\\d+" } # → reward_fn 多模型(冻结 teacher + 可训练 student)是命名模型集;自定义 trainer 读 `self.models["teacher"]`。可跑的端到端模板: [examples/online_distill.py](examples/online_distill.py) -(`lighttrain train -c recipes/online_distill_demo.yaml`)。 +(`lighttrain train -c examples/references/recipes/online_distill_demo.yaml`)。 → [训练范式](docs/concepts/training.zh-CN.md) ## 训练产出 diff --git a/docs/concepts/training.md b/docs/concepts/training.md index 223ba43..2103e49 100644 --- a/docs/concepts/training.md +++ b/docs/concepts/training.md @@ -83,7 +83,7 @@ A custom trainer reaches them as `self.models["teacher"]` / Runnable end-to-end example: a student rolling out on-policy against a frozen teacher — [examples/online_distill.py](../../examples/online_distill.py) -(`lighttrain train -c recipes/online_distill_demo.yaml`). +(`lighttrain train -c examples/references/recipes/online_distill_demo.yaml`). ## PEFT & memory efficiency diff --git a/docs/concepts/training.zh-CN.md b/docs/concepts/training.zh-CN.md index e4db416..986832a 100644 --- a/docs/concepts/training.zh-CN.md +++ b/docs/concepts/training.zh-CN.md @@ -76,7 +76,7 @@ optimizers: 可跑的端到端示例:student 在线 rollout 对抗冻结 teacher—— [examples/online_distill.py](../../examples/online_distill.py) -(`lighttrain train -c recipes/online_distill_demo.yaml`)。 +(`lighttrain train -c examples/references/recipes/online_distill_demo.yaml`)。 ## PEFT 与显存效率 diff --git a/docs/extending/architectures.md b/docs/extending/architectures.md index 3e0b69b..0ec3abd 100644 --- a/docs/extending/architectures.md +++ b/docs/extending/architectures.md @@ -6,12 +6,12 @@ Stateful (RWKV, Mamba) and non-Transformer objectives ship as plugins, selected like any other model/objective: ```bash -lighttrain train -c recipes/pretrain_rwkv.yaml # RWKV stateful pretraining -lighttrain train -c recipes/diffusion_eps.yaml # diffusion eps-prediction -lighttrain train -c recipes/jepa.yaml # JEPA masked-patch prediction -lighttrain train -c recipes/pcn_demo.yaml # Predictive Coding Networks -lighttrain train -c recipes/ff_demo.yaml # Forward-Forward -lighttrain train -c recipes/mezo_sft.yaml # MeZO zero-order SFT +lighttrain train -c examples/references/recipes/pretrain_rwkv.yaml # RWKV stateful pretraining +lighttrain train -c examples/references/recipes/diffusion_eps.yaml # diffusion eps-prediction +lighttrain train -c examples/references/recipes/jepa.yaml # JEPA masked-patch prediction +lighttrain train -c examples/references/recipes/pcn_demo.yaml # Predictive Coding Networks +lighttrain train -c examples/references/recipes/ff_demo.yaml # Forward-Forward +lighttrain train -c examples/references/recipes/mezo_sft.yaml # MeZO zero-order SFT ``` Built-in objectives carry a `loss_family`: `next_token`, `masked_denoising`, diff --git a/docs/extending/architectures.zh-CN.md b/docs/extending/architectures.zh-CN.md index 4f37c10..ad6eefb 100644 --- a/docs/extending/architectures.zh-CN.md +++ b/docs/extending/architectures.zh-CN.md @@ -6,12 +6,12 @@ 一样选用: ```bash -lighttrain train -c recipes/pretrain_rwkv.yaml # RWKV 有状态预训练 -lighttrain train -c recipes/diffusion_eps.yaml # diffusion eps 预测 -lighttrain train -c recipes/jepa.yaml # JEPA 掩码 patch 预测 -lighttrain train -c recipes/pcn_demo.yaml # 预测编码网络 -lighttrain train -c recipes/ff_demo.yaml # Forward-Forward -lighttrain train -c recipes/mezo_sft.yaml # MeZO 零阶 SFT +lighttrain train -c examples/references/recipes/pretrain_rwkv.yaml # RWKV 有状态预训练 +lighttrain train -c examples/references/recipes/diffusion_eps.yaml # diffusion eps 预测 +lighttrain train -c examples/references/recipes/jepa.yaml # JEPA 掩码 patch 预测 +lighttrain train -c examples/references/recipes/pcn_demo.yaml # 预测编码网络 +lighttrain train -c examples/references/recipes/ff_demo.yaml # Forward-Forward +lighttrain train -c examples/references/recipes/mezo_sft.yaml # MeZO 零阶 SFT ``` 内置 objective 带 `loss_family`:`next_token`、`masked_denoising`、 diff --git a/docs/extending/recipes.md b/docs/extending/recipes.md index 05d3bf7..5d65a81 100644 --- a/docs/extending/recipes.md +++ b/docs/extending/recipes.md @@ -3,8 +3,8 @@ > [中文版](recipes.zh-CN.md) · [Docs index](../README.md) The fastest way to start: copy a bundled recipe from -[`recipes/`](../../recipes/) and edit it. Most run with -`lighttrain train -c recipes/.yaml`; the distributed overlays (below) are +[`examples/references/recipes/`](../../examples/references/recipes/) and edit it. Most run with +`lighttrain train -c examples/references/recipes/.yaml`; the distributed overlays (below) are the exception — they layer onto a full recipe and need a multi-process launcher. ## Pretraining & SFT diff --git a/docs/extending/recipes.zh-CN.md b/docs/extending/recipes.zh-CN.md index 2461b39..1f3bd02 100644 --- a/docs/extending/recipes.zh-CN.md +++ b/docs/extending/recipes.zh-CN.md @@ -2,8 +2,8 @@ > [English](recipes.md) · [文档索引](../README.md) -最快的起步方式:从 [`recipes/`](../../recipes/) 拷一个内置 recipe 改。多数 recipe 用 -`lighttrain train -c recipes/<名字>.yaml` 运行;分布式 overlay(见下)是例外—— +最快的起步方式:从 [`examples/references/recipes/`](../../examples/references/recipes/) 拷一个内置 recipe 改。多数 recipe 用 +`lighttrain train -c examples/references/recipes/<名字>.yaml` 运行;分布式 overlay(见下)是例外—— 需叠加到完整 recipe 之上,并用多进程启动器。 ## 预训练与 SFT diff --git a/docs/operations/distributed.md b/docs/operations/distributed.md index 505eadf..7a5bafb 100644 --- a/docs/operations/distributed.md +++ b/docs/operations/distributed.md @@ -60,7 +60,7 @@ engine: { mixed_precision: "no" } ``` Full recipe examples live under -[`recipes/`](../../recipes). +[`examples/references/recipes/`](../../recipes). ## See also diff --git a/docs/operations/distributed.zh-CN.md b/docs/operations/distributed.zh-CN.md index 7e10865..e74b98a 100644 --- a/docs/operations/distributed.zh-CN.md +++ b/docs/operations/distributed.zh-CN.md @@ -57,7 +57,7 @@ engine: { mixed_precision: "no" } ``` 完整 recipe 示例见 -[`recipes/`](../../recipes)。 +[`examples/references/recipes/`](../../recipes)。 ## 相关 diff --git a/examples/README.md b/examples/README.md index ba8ace9..acb9c69 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,25 +1,16 @@ # Examples -One minimal Python script per recipe demonstrating the programmatic API. -Each script can also be run directly, but the CLI (`lighttrain train -c `) -is the recommended entry point for day-to-day use. +Runnable, end-to-end entry points for lighttrain. -| Script | Recipe | What it shows | -|--------|--------|---------------| -| [pretrain_causal.py](pretrain_causal.py) | `pretrain_causal.yaml` | Basic causal LM pretraining | -| [sft_chat.py](sft_chat.py) | `sft_chat.yaml` | Supervised fine-tuning | -| [dpo_offline.py](dpo_offline.py) | `dpo_offline.yaml` | Offline DPO preference training | -| [ppo_online.py](ppo_online.py) | `ppo_online.yaml` | Online PPO RL training | -| [grpo.py](grpo.py) | `grpo.yaml` | GRPO group-relative optimization | -| [student_kd.py](student_kd.py) | `student_kd.yaml` | Knowledge distillation | -| [produce_teacher.py](produce_teacher.py) | `produce_teacher.yaml` | Teacher logit artifact production | -| [qlora.py](qlora.py) | `qlora.yaml` | QLoRA 4-bit fine-tuning | -| [offload_fullparam.py](offload_fullparam.py) | `offload_fullparam.yaml` | LayerOffload full-parameter training | -| [pretrain_rwkv.py](pretrain_rwkv.py) | `pretrain_rwkv.yaml` | Stateful RWKV pretraining | -| [diffusion_eps.py](diffusion_eps.py) | `diffusion_eps.yaml` | Diffusion ε-prediction | -| [jepa.py](jepa.py) | `jepa.yaml` | JEPA joint-embedding predictive arch | -| [pcn_demo.py](pcn_demo.py) | `pcn_demo.yaml` | Predictive Coding Network | -| [ff_demo.py](ff_demo.py) | `ff_demo.yaml` | Forward-Forward algorithm | -| [mezo_sft.py](mezo_sft.py) | `mezo_sft.yaml` | MeZO memory-efficient zeroth-order | -| [sweep_demo.py](sweep_demo.py) | `sweep_demo.yaml` + `sweep_r15.yaml` | Hyperparameter sweep | -| [fork_resume.py](fork_resume.py) | `fork_resume.yaml` | Fork + resume with lineage | +| Directory | What it holds | +|-----------|---------------| +| [`references/`](references) | One minimal script + recipe per built-in capability — the canonical "how do I use feature X" reference set (pretraining, SFT, DPO/PPO/GRPO, distillation, QLoRA, offload, RWKV/diffusion/JEPA, sweeps, fork-resume). The recipes (YAML) live under [`references/recipes/`](references/recipes). | + +Faithful local ports of well-known training repos (e.g. nanoGPT, MiniMind) land +at the top level of this directory, one self-contained folder each. + +Run any recipe via the CLI: + +```bash +lighttrain train -c examples/references/recipes/pretrain_causal.yaml +``` diff --git a/examples/references/README.md b/examples/references/README.md new file mode 100644 index 0000000..bd1081a --- /dev/null +++ b/examples/references/README.md @@ -0,0 +1,30 @@ +# Reference examples + +One minimal Python script per recipe demonstrating the programmatic API. The +matching recipes (YAML configs) live in [`recipes/`](recipes); each script can +also be run directly, but the CLI is the recommended entry point for day-to-day +use: + +```bash +lighttrain train -c examples/references/recipes/pretrain_causal.yaml +``` + +| Script | Recipe | What it shows | +|--------|--------|---------------| +| [pretrain_causal.py](pretrain_causal.py) | `pretrain_causal.yaml` | Basic causal LM pretraining | +| [sft_chat.py](sft_chat.py) | `sft_chat.yaml` | Supervised fine-tuning | +| [dpo_offline.py](dpo_offline.py) | `dpo_offline.yaml` | Offline DPO preference training | +| [ppo_online.py](ppo_online.py) | `ppo_online.yaml` | Online PPO RL training | +| [grpo.py](grpo.py) | `grpo.yaml` | GRPO group-relative optimization | +| [student_kd.py](student_kd.py) | `student_kd.yaml` | Knowledge distillation | +| [produce_teacher.py](produce_teacher.py) | `produce_teacher.yaml` | Teacher logit artifact production | +| [qlora.py](qlora.py) | `qlora.yaml` | QLoRA 4-bit fine-tuning | +| [offload_fullparam.py](offload_fullparam.py) | `offload_fullparam.yaml` | LayerOffload full-parameter training | +| [pretrain_rwkv.py](pretrain_rwkv.py) | `pretrain_rwkv.yaml` | Stateful RWKV pretraining | +| [diffusion_eps.py](diffusion_eps.py) | `diffusion_eps.yaml` | Diffusion ε-prediction | +| [jepa.py](jepa.py) | `jepa.yaml` | JEPA joint-embedding predictive arch | +| [pcn_demo.py](pcn_demo.py) | `pcn_demo.yaml` | Predictive Coding Network | +| [ff_demo.py](ff_demo.py) | `ff_demo.yaml` | Forward-Forward algorithm | +| [mezo_sft.py](mezo_sft.py) | `mezo_sft.yaml` | MeZO memory-efficient zeroth-order | +| [sweep_demo.py](sweep_demo.py) | `sweep_demo.yaml` + `sweep_r15.yaml` | Hyperparameter sweep | +| [fork_resume.py](fork_resume.py) | `fork_resume.yaml` | Fork + resume with lineage | diff --git a/examples/diffusion_eps.py b/examples/references/diffusion_eps.py similarity index 69% rename from examples/diffusion_eps.py rename to examples/references/diffusion_eps.py index 1c46ef8..0107e6e 100644 --- a/examples/diffusion_eps.py +++ b/examples/references/diffusion_eps.py @@ -1,13 +1,13 @@ """Diffusion ε-prediction — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/diffusion_eps.yaml + lighttrain train -c examples/references/recipes/diffusion_eps.yaml """ import lighttrain.builtin_plugins.optim.architectures.diffusion_unet # noqa: F401 from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/diffusion_eps.yaml") +cfg = load_config("examples/references/recipes/diffusion_eps.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/dpo_offline.py b/examples/references/dpo_offline.py similarity index 62% rename from examples/dpo_offline.py rename to examples/references/dpo_offline.py index c8342ca..51191a8 100644 --- a/examples/dpo_offline.py +++ b/examples/references/dpo_offline.py @@ -1,12 +1,12 @@ """Offline DPO — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/dpo_offline.yaml + lighttrain train -c examples/references/recipes/dpo_offline.yaml """ from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/dpo_offline.yaml") +cfg = load_config("examples/references/recipes/dpo_offline.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/ff_demo.py b/examples/references/ff_demo.py similarity index 74% rename from examples/ff_demo.py rename to examples/references/ff_demo.py index 3dc3a72..6cb2bc7 100644 --- a/examples/ff_demo.py +++ b/examples/references/ff_demo.py @@ -1,13 +1,13 @@ """Forward-Forward algorithm — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/ff_demo.yaml + lighttrain train -c examples/references/recipes/ff_demo.yaml """ import lighttrain.builtin_plugins.engine.update_rules.forward_forward # noqa: F401 — registers the ForwardForward update rule from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/ff_demo.yaml") +cfg = load_config("examples/references/recipes/ff_demo.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/fork_resume.py b/examples/references/fork_resume.py similarity index 70% rename from examples/fork_resume.py rename to examples/references/fork_resume.py index eb16751..7f8251b 100644 --- a/examples/fork_resume.py +++ b/examples/references/fork_resume.py @@ -1,9 +1,9 @@ """Fork + resume with 3-generation lineage — programmatic API example (R16). Equivalent CLI sequence: - lighttrain train -c recipes/fork_resume.yaml + lighttrain train -c examples/references/recipes/fork_resume.yaml lighttrain fork --from runs/fork_gen1//checkpoints/step_50 \ - -c recipes/fork_resume.yaml ++optim.lr=1.5e-4 ++exp=fork_gen2 + -c examples/references/recipes/fork_resume.yaml ++optim.lr=1.5e-4 ++exp=fork_gen2 lighttrain resume --run runs/fork_gen2/ """ @@ -19,12 +19,12 @@ checkpoints = list(gen1_ckpt.glob("*/checkpoints/step_*")) if not checkpoints: raise FileNotFoundError( - "No gen1 checkpoint found. Run `lighttrain train -c recipes/fork_resume.yaml` first." + "No gen1 checkpoint found. Run `lighttrain train -c examples/references/recipes/fork_resume.yaml` first." ) ckpt = sorted(checkpoints)[-1] # Fork gen1 → gen2 with halved LR -cfg2 = load_config("recipes/fork_resume.yaml", ["++optim.lr=1.5e-4", "++exp=fork_gen2"]) +cfg2 = load_config("examples/references/recipes/fork_resume.yaml", ["++optim.lr=1.5e-4", "++exp=fork_gen2"]) r2 = fork(ckpt, cfg2) print(f"Gen2 run dir: {r2.new_run_dir}") print(f"Lineage recorded: {r2.lineage_edge_recorded}") diff --git a/examples/grpo.py b/examples/references/grpo.py similarity index 64% rename from examples/grpo.py rename to examples/references/grpo.py index 00a42a3..f96745a 100644 --- a/examples/grpo.py +++ b/examples/references/grpo.py @@ -1,12 +1,12 @@ """GRPO — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/grpo.yaml + lighttrain train -c examples/references/recipes/grpo.yaml """ from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/grpo.yaml") +cfg = load_config("examples/references/recipes/grpo.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/image_cls.py b/examples/references/image_cls.py similarity index 80% rename from examples/image_cls.py rename to examples/references/image_cls.py index 0cc2888..3eeca77 100644 --- a/examples/image_cls.py +++ b/examples/references/image_cls.py @@ -6,12 +6,12 @@ imports them, so no explicit plugin import is needed here. Equivalent CLI: - lighttrain train -c recipes/image_cls.yaml + lighttrain train -c examples/references/recipes/image_cls.yaml """ from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/image_cls.yaml") +cfg = load_config("examples/references/recipes/image_cls.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/jepa.py b/examples/references/jepa.py similarity index 68% rename from examples/jepa.py rename to examples/references/jepa.py index 217412a..d5f6619 100644 --- a/examples/jepa.py +++ b/examples/references/jepa.py @@ -1,12 +1,12 @@ """JEPA joint-embedding predictive architecture — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/jepa.yaml + lighttrain train -c examples/references/recipes/jepa.yaml """ from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/jepa.yaml") +cfg = load_config("examples/references/recipes/jepa.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/lab_components.py b/examples/references/lab_components.py similarity index 100% rename from examples/lab_components.py rename to examples/references/lab_components.py diff --git a/examples/mezo_sft.py b/examples/references/mezo_sft.py similarity index 66% rename from examples/mezo_sft.py rename to examples/references/mezo_sft.py index 696db36..9f26955 100644 --- a/examples/mezo_sft.py +++ b/examples/references/mezo_sft.py @@ -1,12 +1,12 @@ """MeZO memory-efficient zeroth-order SFT — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/mezo_sft.yaml + lighttrain train -c examples/references/recipes/mezo_sft.yaml """ from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/mezo_sft.yaml") +cfg = load_config("examples/references/recipes/mezo_sft.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/offload_fullparam.py b/examples/references/offload_fullparam.py similarity index 70% rename from examples/offload_fullparam.py rename to examples/references/offload_fullparam.py index 21cf694..c40e5ca 100644 --- a/examples/offload_fullparam.py +++ b/examples/references/offload_fullparam.py @@ -1,13 +1,13 @@ """Full-parameter training with LayerOffload — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/offload_fullparam.yaml + lighttrain train -c examples/references/recipes/offload_fullparam.yaml """ import lighttrain.builtin_plugins.layer_offload # registers LayerOffloadEngine # noqa: F401 from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/offload_fullparam.yaml") +cfg = load_config("examples/references/recipes/offload_fullparam.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/online_distill.py b/examples/references/online_distill.py similarity index 99% rename from examples/online_distill.py rename to examples/references/online_distill.py index ac96f89..d33ed60 100644 --- a/examples/online_distill.py +++ b/examples/references/online_distill.py @@ -22,7 +22,7 @@ Run --- - lighttrain train -c recipes/online_distill_demo.yaml + lighttrain train -c examples/references/recipes/online_distill_demo.yaml For real distillation, point the teacher at a pretrained checkpoint (see the recipe). With a random-init teacher the loop still runs end-to-end and the diff --git a/examples/pcn_demo.py b/examples/references/pcn_demo.py similarity index 72% rename from examples/pcn_demo.py rename to examples/references/pcn_demo.py index 806a04d..457bce8 100644 --- a/examples/pcn_demo.py +++ b/examples/references/pcn_demo.py @@ -1,13 +1,13 @@ """Predictive Coding Network — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/pcn_demo.yaml + lighttrain train -c examples/references/recipes/pcn_demo.yaml """ import lighttrain.builtin_plugins.engine.update_rules.pcn # noqa: F401 — registers the PCN update rule from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/pcn_demo.yaml") +cfg = load_config("examples/references/recipes/pcn_demo.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/ppo_online.py b/examples/references/ppo_online.py similarity index 63% rename from examples/ppo_online.py rename to examples/references/ppo_online.py index e7779e1..4888e2a 100644 --- a/examples/ppo_online.py +++ b/examples/references/ppo_online.py @@ -1,12 +1,12 @@ """Online PPO — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/ppo_online.yaml + lighttrain train -c examples/references/recipes/ppo_online.yaml """ from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/ppo_online.yaml") +cfg = load_config("examples/references/recipes/ppo_online.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/pretrain_causal.py b/examples/references/pretrain_causal.py similarity index 58% rename from examples/pretrain_causal.py rename to examples/references/pretrain_causal.py index 3019f59..7e888d1 100644 --- a/examples/pretrain_causal.py +++ b/examples/references/pretrain_causal.py @@ -1,12 +1,12 @@ """Causal LM pretraining — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/pretrain_causal.yaml + lighttrain train -c examples/references/recipes/pretrain_causal.yaml """ from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/pretrain_causal.yaml", ["++trainer.max_steps=100"]) +cfg = load_config("examples/references/recipes/pretrain_causal.yaml", ["++trainer.max_steps=100"]) bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/pretrain_rwkv.py b/examples/references/pretrain_rwkv.py similarity index 71% rename from examples/pretrain_rwkv.py rename to examples/references/pretrain_rwkv.py index 9d867d7..899a50a 100644 --- a/examples/pretrain_rwkv.py +++ b/examples/references/pretrain_rwkv.py @@ -1,13 +1,13 @@ """Stateful RWKV pretraining — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/pretrain_rwkv.yaml + lighttrain train -c examples/references/recipes/pretrain_rwkv.yaml """ import lighttrain.builtin_plugins.optim.architectures.rwkv # registers TinyRWKVModel # noqa: F401 from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/pretrain_rwkv.yaml") +cfg = load_config("examples/references/recipes/pretrain_rwkv.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/produce_teacher.py b/examples/references/produce_teacher.py similarity index 55% rename from examples/produce_teacher.py rename to examples/references/produce_teacher.py index c167a90..a86cf3e 100644 --- a/examples/produce_teacher.py +++ b/examples/references/produce_teacher.py @@ -1,12 +1,12 @@ """Produce teacher logit artifacts — programmatic API example. Equivalent CLI: - lighttrain produce-artifact -c recipes/produce_teacher.yaml + lighttrain produce-artifact -c examples/references/recipes/produce_teacher.yaml """ from pathlib import Path from lighttrain.cli._produce import run_produce -manifest = run_produce(Path("recipes/produce_teacher.yaml")) +manifest = run_produce(Path("examples/references/recipes/produce_teacher.yaml")) print(f"Artifact finalized → {manifest}") diff --git a/examples/qlora.py b/examples/references/qlora.py similarity index 75% rename from examples/qlora.py rename to examples/references/qlora.py index 1240a91..d02d192 100644 --- a/examples/qlora.py +++ b/examples/references/qlora.py @@ -3,13 +3,13 @@ Requires: pip install -e '.[quant,peft]' Equivalent CLI: - lighttrain train -c recipes/qlora.yaml + lighttrain train -c examples/references/recipes/qlora.yaml """ import lighttrain.builtin_plugins.quant # registers BNB / QLoRA adapters # noqa: F401 from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/qlora.yaml") +cfg = load_config("examples/references/recipes/qlora.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/recipes/ddp.yaml b/examples/references/recipes/ddp.yaml similarity index 92% rename from recipes/ddp.yaml rename to examples/references/recipes/ddp.yaml index 4033b4e..7471608 100644 --- a/recipes/ddp.yaml +++ b/examples/references/recipes/ddp.yaml @@ -1,5 +1,5 @@ # Single-machine 4-GPU DDP training. -# Launch: torchrun --nproc_per_node 4 -m lighttrain.cli train -c recipes/ddp.yaml +# Launch: torchrun --nproc_per_node 4 -m lighttrain.cli train -c examples/references/recipes/ddp.yaml # # Parallel topology: dp=4 (data-parallel only) diff --git a/recipes/diffusion_eps.yaml b/examples/references/recipes/diffusion_eps.yaml similarity index 92% rename from recipes/diffusion_eps.yaml rename to examples/references/recipes/diffusion_eps.yaml index d4de8b6..4cf1ccd 100644 --- a/recipes/diffusion_eps.yaml +++ b/examples/references/recipes/diffusion_eps.yaml @@ -8,7 +8,7 @@ # required. Loss should decrease monotonically over 200 steps. # # Run with: -# lighttrain train -c recipes/diffusion_eps.yaml +# lighttrain train -c examples/references/recipes/diffusion_eps.yaml mode: lab seed: 7 @@ -16,7 +16,7 @@ exp: r8_diffusion run_root: runs # Demo-only toy dataset/collator (synthetic_signal / signal); not a core component. -user_modules: [examples/lab_components.py] +user_modules: [examples/references/lab_components.py] model: default model_profiles: diff --git a/recipes/dpo_offline.yaml b/examples/references/recipes/dpo_offline.yaml similarity index 91% rename from recipes/dpo_offline.yaml rename to examples/references/recipes/dpo_offline.yaml index 2a2111e..3043cd2 100644 --- a/recipes/dpo_offline.yaml +++ b/examples/references/recipes/dpo_offline.yaml @@ -1,11 +1,11 @@ # R4 — Offline DPO with artifact-cached reference logprobs (DESIGN §15.2 / §26.8). # # Requires a pre-built reference-logprob artifact at `artifacts/ref_logprobs_v1`. -# Produce it first with `lighttrain produce-artifact -c recipes/produce_ref_logprobs.yaml` -# or by running `recipes/produce_teacher.yaml` adapted to output per-sample logprobs. +# Produce it first with `lighttrain produce-artifact -c examples/references/recipes/produce_ref_logprobs.yaml` +# or by running `examples/references/recipes/produce_teacher.yaml` adapted to output per-sample logprobs. # # Run with: -# lighttrain train -c recipes/dpo_offline.yaml +# lighttrain train -c examples/references/recipes/dpo_offline.yaml mode: lab seed: 42 diff --git a/recipes/ff_demo.yaml b/examples/references/recipes/ff_demo.yaml similarity index 91% rename from recipes/ff_demo.yaml rename to examples/references/recipes/ff_demo.yaml index 66bc411..b38e56d 100644 --- a/recipes/ff_demo.yaml +++ b/examples/references/recipes/ff_demo.yaml @@ -6,7 +6,7 @@ # # Run with: # python -c "from lighttrain.builtin_plugins.update_rules.forward_forward import ForwardForwardUpdateRule" -# lighttrain train -c recipes/ff_demo.yaml +# lighttrain train -c examples/references/recipes/ff_demo.yaml mode: lab seed: 77 @@ -14,7 +14,7 @@ exp: r10_ff run_root: runs # Demo-only toy model/dataset/collator (mlp_toy / synthetic_binary / x_labels); not core. -user_modules: [examples/lab_components.py] +user_modules: [examples/references/lab_components.py] model: default model_profiles: diff --git a/recipes/fork_resume.yaml b/examples/references/recipes/fork_resume.yaml similarity index 89% rename from recipes/fork_resume.yaml rename to examples/references/recipes/fork_resume.yaml index 1af8939..2a57325 100644 --- a/recipes/fork_resume.yaml +++ b/examples/references/recipes/fork_resume.yaml @@ -2,14 +2,14 @@ # # Workflow (R16): # Step 1 — Train gen-1 for 50 steps: -# lighttrain train -c recipes/fork_resume.yaml +# lighttrain train -c examples/references/recipes/fork_resume.yaml # # Step 2 — Fork gen-1 checkpoint with halved LR (gen-2): # python - <<'EOF' # from pathlib import Path # from lighttrain.lab.fork import fork # from lighttrain.config import load_config -# cfg = load_config("recipes/fork_resume.yaml", ["++optim.lr=1.5e-4", "++exp=fork_gen2"]) +# cfg = load_config("examples/references/recipes/fork_resume.yaml", ["++optim.lr=1.5e-4", "++exp=fork_gen2"]) # report = fork(Path("runs/fork_gen1//checkpoints/step_50"), cfg) # print(report.new_run_dir) # EOF diff --git a/recipes/fsdp.yaml b/examples/references/recipes/fsdp.yaml similarity index 92% rename from recipes/fsdp.yaml rename to examples/references/recipes/fsdp.yaml index d17f249..063de5f 100644 --- a/recipes/fsdp.yaml +++ b/examples/references/recipes/fsdp.yaml @@ -1,5 +1,5 @@ # Single-machine 8-GPU FSDP training (ZeRO-3 equivalent). -# Launch: torchrun --nproc_per_node 8 -m lighttrain.cli train -c recipes/fsdp.yaml +# Launch: torchrun --nproc_per_node 8 -m lighttrain.cli train -c examples/references/recipes/fsdp.yaml parallel: backend: nccl diff --git a/recipes/grpo.yaml b/examples/references/recipes/grpo.yaml similarity index 98% rename from recipes/grpo.yaml rename to examples/references/recipes/grpo.yaml index ee19de3..c75ca72 100644 --- a/recipes/grpo.yaml +++ b/examples/references/recipes/grpo.yaml @@ -5,7 +5,7 @@ # applies a clipped surrogate update without a value model. # # Run with: -# lighttrain train -c recipes/grpo.yaml +# lighttrain train -c examples/references/recipes/grpo.yaml mode: lab seed: 99 diff --git a/recipes/image_cls.yaml b/examples/references/recipes/image_cls.yaml similarity index 91% rename from recipes/image_cls.yaml rename to examples/references/recipes/image_cls.yaml index df570e6..dd3dd21 100644 --- a/recipes/image_cls.yaml +++ b/examples/references/recipes/image_cls.yaml @@ -6,7 +6,7 @@ # and `acc` rise over 200 steps on the synthetic dataset. # # Run with: -# lighttrain train -c recipes/image_cls.yaml +# lighttrain train -c examples/references/recipes/image_cls.yaml mode: lab seed: 7 @@ -14,7 +14,7 @@ exp: r_image_cls run_root: runs # Demo-only synthetic dataset (synthetic_image); not a core component. -user_modules: [examples/vision_components.py] +user_modules: [examples/references/vision_components.py] model: default model_profiles: diff --git a/recipes/jepa.yaml b/examples/references/recipes/jepa.yaml similarity index 93% rename from recipes/jepa.yaml rename to examples/references/recipes/jepa.yaml index a50eace..2a9a3f9 100644 --- a/recipes/jepa.yaml +++ b/examples/references/recipes/jepa.yaml @@ -5,7 +5,7 @@ # given only the context patches. # # Run with: -# lighttrain train -c recipes/jepa.yaml +# lighttrain train -c examples/references/recipes/jepa.yaml mode: lab seed: 13 @@ -13,7 +13,7 @@ exp: r9_jepa run_root: runs # Demo-only toy dataset/collator (synthetic_patches / patches); not a core component. -user_modules: [examples/lab_components.py] +user_modules: [examples/references/lab_components.py] model: default model_profiles: diff --git a/recipes/mezo_sft.yaml b/examples/references/recipes/mezo_sft.yaml similarity index 91% rename from recipes/mezo_sft.yaml rename to examples/references/recipes/mezo_sft.yaml index e926e6d..93131d8 100644 --- a/recipes/mezo_sft.yaml +++ b/examples/references/recipes/mezo_sft.yaml @@ -5,7 +5,7 @@ # Loss should decrease; model.parameters()[0].grad must remain None. # # Run with: -# lighttrain train -c recipes/mezo_sft.yaml +# lighttrain train -c examples/references/recipes/mezo_sft.yaml mode: lab seed: 42 @@ -13,7 +13,7 @@ exp: r11_mezo run_root: runs # Demo-only toy dataset (sft_jsonl); not a core component. -user_modules: [examples/lab_components.py] +user_modules: [examples/references/lab_components.py] model: default model_profiles: diff --git a/recipes/nano_fsdp.yaml b/examples/references/recipes/nano_fsdp.yaml similarity index 96% rename from recipes/nano_fsdp.yaml rename to examples/references/recipes/nano_fsdp.yaml index b2ed358..cbc3c40 100644 --- a/recipes/nano_fsdp.yaml +++ b/examples/references/recipes/nano_fsdp.yaml @@ -1,6 +1,6 @@ # nano_fsdp.yaml — real-GPU FSDP (ZeRO-3) smoke on the tiny_lm model. # Same model/data as nano_model.yaml but FSDP FULL_SHARD over NCCL instead of CPU-gloo DDP. -# Launch: torchrun --nproc_per_node=4 -m lighttrain.cli train -c recipes/nano_fsdp.yaml +# Launch: torchrun --nproc_per_node=4 -m lighttrain.cli train -c examples/references/recipes/nano_fsdp.yaml parallel: backend: nccl diff --git a/recipes/nano_model.yaml b/examples/references/recipes/nano_model.yaml similarity index 96% rename from recipes/nano_model.yaml rename to examples/references/recipes/nano_model.yaml index eaf126e..587aefc 100644 --- a/recipes/nano_model.yaml +++ b/examples/references/recipes/nano_model.yaml @@ -1,7 +1,7 @@ # nano_model.yaml — gloo + CPU multi-process communication test # Purpose: verify gloo process group init, DDP AllReduce, and full training loop without deadlock. # -# Launch: torchrun --nproc_per_node=4 -m lighttrain.cli train -c recipes/nano_model.yaml +# Launch: torchrun --nproc_per_node=4 -m lighttrain.cli train -c examples/references/recipes/nano_model.yaml # # Model size: ~115K params (embed 16K + 2 × Transformer layers ~50K each) diff --git a/recipes/nano_zero2.yaml b/examples/references/recipes/nano_zero2.yaml similarity index 96% rename from recipes/nano_zero2.yaml rename to examples/references/recipes/nano_zero2.yaml index 3e326b5..89b492e 100644 --- a/recipes/nano_zero2.yaml +++ b/examples/references/recipes/nano_zero2.yaml @@ -1,6 +1,6 @@ # nano_zero2.yaml — real-GPU DeepSpeed ZeRO-2 smoke on the tiny_lm model. # Same model/data as nano_model.yaml but ZeRO-2 over NCCL instead of CPU-gloo DDP. -# Launch: torchrun --nproc_per_node=4 -m lighttrain.cli train -c recipes/nano_zero2.yaml +# Launch: torchrun --nproc_per_node=4 -m lighttrain.cli train -c examples/references/recipes/nano_zero2.yaml parallel: backend: nccl diff --git a/recipes/offload_fullparam.yaml b/examples/references/recipes/offload_fullparam.yaml similarity index 88% rename from recipes/offload_fullparam.yaml rename to examples/references/recipes/offload_fullparam.yaml index bfacc1a..45a71c7 100644 --- a/recipes/offload_fullparam.yaml +++ b/examples/references/recipes/offload_fullparam.yaml @@ -1,6 +1,6 @@ # R12 — Full-parameter training with LayerOffloadEngine (DESIGN §14 / §26.7). # -# Drop-in replacement for recipes/pretrain_causal.yaml that: +# Drop-in replacement for examples/references/recipes/pretrain_causal.yaml that: # * swaps engine.name = "standard" → "layer_offload" # * uses optim.name = "cpu_offload" so optimizer state lives on host # * keeps resident_layers=2 + prefetch=1 (DESIGN §14.1 defaults) @@ -11,8 +11,8 @@ # WSL acceptance (docs/M5_INTERFACES.md): # pip install -e ".[peft,quant,dev]" # pytest -m heavy -k r12 -# lighttrain estimate -c recipes/offload_fullparam.yaml --json r12.json -# lighttrain train -c recipes/offload_fullparam.yaml +# lighttrain estimate -c examples/references/recipes/offload_fullparam.yaml --json r12.json +# lighttrain train -c examples/references/recipes/offload_fullparam.yaml mode: lab seed: 1337 diff --git a/recipes/online_distill_demo.yaml b/examples/references/recipes/online_distill_demo.yaml similarity index 88% rename from recipes/online_distill_demo.yaml rename to examples/references/recipes/online_distill_demo.yaml index de3790d..c92c8ec 100644 --- a/recipes/online_distill_demo.yaml +++ b/examples/references/recipes/online_distill_demo.yaml @@ -2,17 +2,17 @@ # # The student generates its own completions on-policy; a FROZEN, *separate* # teacher scores each sampled token; a REINFORCE update moves the student toward -# the teacher. The custom trainer lives in examples/online_distill.py and is +# the teacher. The custom trainer lives in examples/references/online_distill.py and is # loaded purely through `user_modules:` (zero core edits). # -# lighttrain train -c recipes/online_distill_demo.yaml +# lighttrain train -c examples/references/recipes/online_distill_demo.yaml # # This is the in-repo template for the multi-model + online-RL seam documented in # docs/registry_and_protocols.md §4.11 (the shape OPD / self-rewarding / GAN need, # which the built-in ppo/grpo trainers can't host). # # For REAL distillation, pretrain a teacher and point teacher.checkpoint at it: -# lighttrain train -c recipes/pretrain_causal.yaml exp=teacher trainer.max_steps=500 +# lighttrain train -c examples/references/recipes/pretrain_causal.yaml exp=teacher trainer.max_steps=500 # # then set models.teacher.checkpoint: runs/teacher/<...>/checkpoints/step_500 # With the checkpoint omitted the teacher is random-init: the loop still runs and # `reverse_kl` still descends (the student matches whatever fixed teacher it is given). @@ -23,7 +23,7 @@ exp: online_distill_demo run_root: runs user_modules: - - examples/online_distill.py + - examples/references/online_distill.py # Two models via the `models:` set — the seam custom paradigms read as # self.models["student"] / self.models["teacher"]. diff --git a/recipes/pcn_demo.yaml b/examples/references/recipes/pcn_demo.yaml similarity index 91% rename from recipes/pcn_demo.yaml rename to examples/references/recipes/pcn_demo.yaml index 7146457..999d390 100644 --- a/recipes/pcn_demo.yaml +++ b/examples/references/recipes/pcn_demo.yaml @@ -6,7 +6,7 @@ # # Run with: # python -c "from lighttrain.builtin_plugins.update_rules.pcn import PCNUpdateRule" -# lighttrain train -c recipes/pcn_demo.yaml +# lighttrain train -c examples/references/recipes/pcn_demo.yaml mode: lab seed: 42 @@ -14,7 +14,7 @@ exp: r10_pcn run_root: runs # Demo-only toy model/dataset/collator (mlp_toy / synthetic_binary / x_labels); not core. -user_modules: [examples/lab_components.py] +user_modules: [examples/references/lab_components.py] model: default model_profiles: diff --git a/recipes/ppo_online.yaml b/examples/references/recipes/ppo_online.yaml similarity index 98% rename from recipes/ppo_online.yaml rename to examples/references/recipes/ppo_online.yaml index 5416ff8..615f348 100644 --- a/recipes/ppo_online.yaml +++ b/examples/references/recipes/ppo_online.yaml @@ -7,7 +7,7 @@ # 4. Compute GAE advantages; run K PPO inner epochs over the buffer. # # Run with: -# lighttrain train -c recipes/ppo_online.yaml +# lighttrain train -c examples/references/recipes/ppo_online.yaml # # Note: the reward_fn is wired in code by PPOTrainer; this recipe shows the # config structure. For a real task, replace `verify_pattern` with a task- diff --git a/recipes/pretrain_causal.yaml b/examples/references/recipes/pretrain_causal.yaml similarity index 100% rename from recipes/pretrain_causal.yaml rename to examples/references/recipes/pretrain_causal.yaml diff --git a/recipes/pretrain_rwkv.yaml b/examples/references/recipes/pretrain_rwkv.yaml similarity index 96% rename from recipes/pretrain_rwkv.yaml rename to examples/references/recipes/pretrain_rwkv.yaml index f1e2c61..93d3603 100644 --- a/recipes/pretrain_rwkv.yaml +++ b/examples/references/recipes/pretrain_rwkv.yaml @@ -6,7 +6,7 @@ # # Run with: # python -c "from lighttrain.builtin_plugins.architectures.rwkv import TinyRWKVModel" -# lighttrain train -c recipes/pretrain_rwkv.yaml +# lighttrain train -c examples/references/recipes/pretrain_rwkv.yaml mode: lab seed: 42 diff --git a/recipes/produce_teacher.yaml b/examples/references/recipes/produce_teacher.yaml similarity index 87% rename from recipes/produce_teacher.yaml rename to examples/references/recipes/produce_teacher.yaml index 77d0215..42beff1 100644 --- a/recipes/produce_teacher.yaml +++ b/examples/references/recipes/produce_teacher.yaml @@ -1,9 +1,9 @@ # R3 — Stage 1: offline teacher logits / hidden-states production (DESIGN §12.9). # # Produces a `safetensors-shards` artifact at `artifacts/teacher_tiny_v1/` that -# downstream `recipes/student_kd.yaml` joins via ArtifactJoinedDataset. +# downstream `examples/references/recipes/student_kd.yaml` joins via ArtifactJoinedDataset. # Run with: -# lighttrain produce-artifact -c recipes/produce_teacher.yaml +# lighttrain produce-artifact -c examples/references/recipes/produce_teacher.yaml mode: lab seed: 7 diff --git a/recipes/qlora.yaml b/examples/references/recipes/qlora.yaml similarity index 90% rename from recipes/qlora.yaml rename to examples/references/recipes/qlora.yaml index 77cd2a8..9aca303 100644 --- a/recipes/qlora.yaml +++ b/examples/references/recipes/qlora.yaml @@ -7,8 +7,8 @@ # WSL acceptance (docs/M5_INTERFACES.md): # pip install -e ".[peft,quant,dev]" # pytest -m heavy -k r13 -# lighttrain estimate -c recipes/qlora.yaml # trainable < 1% -# lighttrain train -c recipes/qlora.yaml # 200 steps; loss drops +# lighttrain estimate -c examples/references/recipes/qlora.yaml # trainable < 1% +# lighttrain train -c examples/references/recipes/qlora.yaml # 200 steps; loss drops mode: lab seed: 42 diff --git a/recipes/sft_chat.yaml b/examples/references/recipes/sft_chat.yaml similarity index 95% rename from recipes/sft_chat.yaml rename to examples/references/recipes/sft_chat.yaml index 5f22db5..9c81477 100644 --- a/recipes/sft_chat.yaml +++ b/examples/references/recipes/sft_chat.yaml @@ -2,7 +2,7 @@ # # Runs on CPU. Drives PrepGraph end-to-end: load → tokenize → validate → # pack → materialize, then trains a tiny causal LM on the packed sequences. -# Identical to recipes/pretrain_causal.yaml except for the data path. +# Identical to examples/references/recipes/pretrain_causal.yaml except for the data path. mode: lab seed: 1337 diff --git a/recipes/sft_chat_hf.yaml b/examples/references/recipes/sft_chat_hf.yaml similarity index 100% rename from recipes/sft_chat_hf.yaml rename to examples/references/recipes/sft_chat_hf.yaml diff --git a/recipes/student_kd.yaml b/examples/references/recipes/student_kd.yaml similarity index 91% rename from recipes/student_kd.yaml rename to examples/references/recipes/student_kd.yaml index 3540f0c..d324779 100644 --- a/recipes/student_kd.yaml +++ b/examples/references/recipes/student_kd.yaml @@ -1,9 +1,9 @@ # R3 — Stage 2: student distillation training (DESIGN §12.9). # -# Joins the teacher artifact produced by `recipes/produce_teacher.yaml` and +# Joins the teacher artifact produced by `examples/references/recipes/produce_teacher.yaml` and # trains a smaller TinyLM with the CE + KL_topk + hidden_mse composite loss. # Run with: -# lighttrain train -c recipes/student_kd.yaml +# lighttrain train -c examples/references/recipes/student_kd.yaml mode: lab seed: 17 diff --git a/recipes/sweep_demo.yaml b/examples/references/recipes/sweep_demo.yaml similarity index 91% rename from recipes/sweep_demo.yaml rename to examples/references/recipes/sweep_demo.yaml index d81a1f5..e5e1b42 100644 --- a/recipes/sweep_demo.yaml +++ b/examples/references/recipes/sweep_demo.yaml @@ -4,7 +4,7 @@ # The sweep spec file (sweep_r15.yaml) injects LR / weight-decay overrides. # # Run the sweep: -# lighttrain sweep -c recipes/sweep_demo.yaml -s recipes/sweep_r15.yaml +# lighttrain sweep -c examples/references/recipes/sweep_demo.yaml -s examples/references/recipes/sweep_r15.yaml mode: lab seed: 1337 diff --git a/recipes/sweep_lr.yaml b/examples/references/recipes/sweep_lr.yaml similarity index 84% rename from recipes/sweep_lr.yaml rename to examples/references/recipes/sweep_lr.yaml index 43a0105..f9d7ffd 100644 --- a/recipes/sweep_lr.yaml +++ b/examples/references/recipes/sweep_lr.yaml @@ -1,10 +1,10 @@ # R15 LR sweep base config (DESIGN §25.1 R15 canonical name). # # Identical to sweep_demo.yaml; exists so the DESIGN §25.1 recipe reference -# resolves to an actual file. The sweep spec is recipes/sweep_r15.yaml. +# resolves to an actual file. The sweep spec is examples/references/recipes/sweep_r15.yaml. # # Run: -# lighttrain sweep -c recipes/sweep_lr.yaml -s recipes/sweep_r15.yaml +# lighttrain sweep -c examples/references/recipes/sweep_lr.yaml -s examples/references/recipes/sweep_r15.yaml mode: lab seed: 1337 diff --git a/recipes/sweep_r15.yaml b/examples/references/recipes/sweep_r15.yaml similarity index 72% rename from recipes/sweep_r15.yaml rename to examples/references/recipes/sweep_r15.yaml index b327589..fe739ed 100644 --- a/recipes/sweep_r15.yaml +++ b/examples/references/recipes/sweep_r15.yaml @@ -3,7 +3,7 @@ # 3 × 3 = 9 trials (≥ 8 required by R15). # # Usage: -# lighttrain sweep -c recipes/sweep_demo.yaml -s recipes/sweep_r15.yaml +# lighttrain sweep -c examples/references/recipes/sweep_demo.yaml -s examples/references/recipes/sweep_r15.yaml name: r15_lr_wd metric: loss diff --git a/recipes/vlm_sft.yaml b/examples/references/recipes/vlm_sft.yaml similarity index 100% rename from recipes/vlm_sft.yaml rename to examples/references/recipes/vlm_sft.yaml diff --git a/recipes/zero2.yaml b/examples/references/recipes/zero2.yaml similarity index 74% rename from recipes/zero2.yaml rename to examples/references/recipes/zero2.yaml index 8d9b96e..f85da53 100644 --- a/recipes/zero2.yaml +++ b/examples/references/recipes/zero2.yaml @@ -1,6 +1,6 @@ # 8-GPU DeepSpeed ZeRO-2 training. -# Launch: deepspeed --num_gpus 8 -m lighttrain.cli train -c recipes/zero2.yaml -# Or: torchrun --nproc_per_node 8 -m lighttrain.cli train -c recipes/zero2.yaml +# Launch: deepspeed --num_gpus 8 -m lighttrain.cli train -c examples/references/recipes/zero2.yaml +# Or: torchrun --nproc_per_node 8 -m lighttrain.cli train -c examples/references/recipes/zero2.yaml parallel: backend: nccl diff --git a/examples/sft_chat.py b/examples/references/sft_chat.py similarity index 64% rename from examples/sft_chat.py rename to examples/references/sft_chat.py index 2761027..b7a17ab 100644 --- a/examples/sft_chat.py +++ b/examples/references/sft_chat.py @@ -1,12 +1,12 @@ """Supervised fine-tuning — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/sft_chat.yaml + lighttrain train -c examples/references/recipes/sft_chat.yaml """ from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/sft_chat.yaml") +cfg = load_config("examples/references/recipes/sft_chat.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/sft_chat_hf.py b/examples/references/sft_chat_hf.py similarity index 65% rename from examples/sft_chat_hf.py rename to examples/references/sft_chat_hf.py index 234df45..538140f 100644 --- a/examples/sft_chat_hf.py +++ b/examples/references/sft_chat_hf.py @@ -1,12 +1,12 @@ """SFT with HuggingFace model backend — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/sft_chat_hf.yaml + lighttrain train -c examples/references/recipes/sft_chat_hf.yaml """ from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/sft_chat_hf.yaml") +cfg = load_config("examples/references/recipes/sft_chat_hf.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/student_kd.py b/examples/references/student_kd.py similarity index 66% rename from examples/student_kd.py rename to examples/references/student_kd.py index 8f04898..5bb0b24 100644 --- a/examples/student_kd.py +++ b/examples/references/student_kd.py @@ -1,12 +1,12 @@ """Knowledge distillation from teacher logits — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/student_kd.yaml + lighttrain train -c examples/references/recipes/student_kd.yaml """ from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/student_kd.yaml") +cfg = load_config("examples/references/recipes/student_kd.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/examples/sweep_demo.py b/examples/references/sweep_demo.py similarity index 68% rename from examples/sweep_demo.py rename to examples/references/sweep_demo.py index b8ee713..d18e8b2 100644 --- a/examples/sweep_demo.py +++ b/examples/references/sweep_demo.py @@ -1,7 +1,7 @@ """Hyperparameter sweep — programmatic API example (R15). Equivalent CLI: - lighttrain sweep -c recipes/sweep_demo.yaml -s recipes/sweep_r15.yaml + lighttrain sweep -c examples/references/recipes/sweep_demo.yaml -s examples/references/recipes/sweep_r15.yaml """ from pathlib import Path @@ -10,8 +10,8 @@ from lighttrain.lab.sweep import SweepRunner runner = SweepRunner( - Path("recipes/sweep_demo.yaml"), - Path("recipes/sweep_r15.yaml"), + Path("examples/references/recipes/sweep_demo.yaml"), + Path("examples/references/recipes/sweep_r15.yaml"), strategy="grid", ) report = runner.run() diff --git a/examples/vision_components.py b/examples/references/vision_components.py similarity index 100% rename from examples/vision_components.py rename to examples/references/vision_components.py diff --git a/examples/vlm_sft.py b/examples/references/vlm_sft.py similarity index 65% rename from examples/vlm_sft.py rename to examples/references/vlm_sft.py index a7de7dc..45bcb35 100644 --- a/examples/vlm_sft.py +++ b/examples/references/vlm_sft.py @@ -1,12 +1,12 @@ """Vision-Language Model SFT — programmatic API example. Equivalent CLI: - lighttrain train -c recipes/vlm_sft.yaml + lighttrain train -c examples/references/recipes/vlm_sft.yaml """ from lighttrain.cli._runtime import setup_run_from_config from lighttrain.config import load_config -cfg = load_config("recipes/vlm_sft.yaml") +cfg = load_config("examples/references/recipes/vlm_sft.yaml") bundle = setup_run_from_config(cfg) bundle["trainer"].fit() diff --git a/lighttrain/builtin_plugins/data/processors/image.py b/lighttrain/builtin_plugins/data/processors/image.py index 6d0f5fa..df19e43 100644 --- a/lighttrain/builtin_plugins/data/processors/image.py +++ b/lighttrain/builtin_plugins/data/processors/image.py @@ -3,7 +3,7 @@ Two flavours: * ``SimpleImageProcessor`` — Pillow-only, hermetic. Resize + CHW float32 - normalize. Default for tests and ``recipes/vlm_sft.yaml`` when no HF model + normalize. Default for tests and ``examples/references/recipes/vlm_sft.yaml`` when no HF model is available. * ``HFImageProcessor`` — wraps ``transformers.AutoImageProcessor``; lazy diff --git a/lighttrain/builtin_plugins/data/processors/text.py b/lighttrain/builtin_plugins/data/processors/text.py index 64eeeae..319e4fd 100644 --- a/lighttrain/builtin_plugins/data/processors/text.py +++ b/lighttrain/builtin_plugins/data/processors/text.py @@ -8,7 +8,7 @@ * ``ChatTemplateProcessor`` — hermetic byte-tokenizer-friendly chat templater that needs no model files. Uses Python f-strings as the template language (``{system}{user}{assistant}``), so it's enough for tests and the default - ``recipes/sft_chat.yaml``. + ``examples/references/recipes/sft_chat.yaml``. """ from __future__ import annotations diff --git a/lighttrain/builtin_plugins/losses/distill.py b/lighttrain/builtin_plugins/losses/distill.py index 1c2eeda..b5c9dfb 100644 --- a/lighttrain/builtin_plugins/losses/distill.py +++ b/lighttrain/builtin_plugins/losses/distill.py @@ -6,7 +6,7 @@ Tensor naming convention ------------------------ -Producer side (see ``recipes/produce_teacher.yaml``) writes: +Producer side (see ``examples/references/recipes/produce_teacher.yaml``) writes: * ``logits_topk_64.values`` (B, T, K) * ``logits_topk_64.indices`` (B, T, K) (int32) diff --git a/lighttrain/cli/commands/artifacts.py b/lighttrain/cli/commands/artifacts.py index dce4f43..3e411c1 100644 --- a/lighttrain/cli/commands/artifacts.py +++ b/lighttrain/cli/commands/artifacts.py @@ -137,11 +137,11 @@ def export_cmd( # Export as HuggingFace model directory (requires --config) lighttrain export --to hf --ckpt runs/exp/run_001/checkpoints/step_500 \\ - --config recipes/pretrain_causal.yaml --out hf_model/ + --config examples/references/recipes/pretrain_causal.yaml --out hf_model/ # Export as GGUF (requires llama.cpp convert script on PATH) lighttrain export --to gguf --ckpt runs/exp/run_001/checkpoints/step_500 \\ - --config recipes/pretrain_causal.yaml --out model.gguf + --config examples/references/recipes/pretrain_causal.yaml --out model.gguf """ import torch diff --git a/lighttrain/cli/commands/experiment.py b/lighttrain/cli/commands/experiment.py index be68fe1..139cab6 100644 --- a/lighttrain/cli/commands/experiment.py +++ b/lighttrain/cli/commands/experiment.py @@ -26,7 +26,7 @@ def sweep_cmd( \\b Example: - lighttrain sweep -c recipes/sweep_demo.yaml -s recipes/sweep_r15.yaml + lighttrain sweep -c examples/references/recipes/sweep_demo.yaml -s examples/references/recipes/sweep_r15.yaml """ from lighttrain.lab.auto_report import write_sweep_report from lighttrain.lab.sweep import SweepRunner @@ -150,7 +150,7 @@ def fork_cmd( \\b Example: lighttrain fork --from runs/exp/run_001/checkpoints/step_500 \\ - -c recipes/pretrain_causal.yaml ++optim.lr=1e-4 + -c examples/references/recipes/pretrain_causal.yaml ++optim.lr=1e-4 """ from lighttrain.lab.fork import fork diff --git a/lighttrain/cli/commands/scaffold.py b/lighttrain/cli/commands/scaffold.py index 3c948ea..034b142 100644 --- a/lighttrain/cli/commands/scaffold.py +++ b/lighttrain/cli/commands/scaffold.py @@ -129,7 +129,7 @@ # ============================================================================= # --- A. SFT over chat data (PrepGraph) --------------------------------------- -# Replace data: with a prep_graph data module; see recipes/sft_chat.yaml. +# Replace data: with a prep_graph data module; see examples/references/recipes/sft_chat.yaml. # --- B. Model variants (model_profiles) -------------------------------------- # Swap on the CLI with `model=big`; tweak with `model_profiles.base.d_model=384`. @@ -140,7 +140,7 @@ # --- C. Multi-model: frozen teacher + trainable student ---------------------- # A custom trainer reads self.models["teacher"] / self.optimizers["student"]. -# See examples/online_distill.py and recipes/online_distill_demo.yaml. +# See examples/references/online_distill.py and examples/references/recipes/online_distill_demo.yaml. # models: # student: { spec: { name: tiny_lm, d_model: 128, n_layers: 4, n_heads: 4 }, trainable: true, optimizer: main } # teacher: { spec: { name: tiny_lm, d_model: 128, n_layers: 4, n_heads: 4 }, trainable: false, checkpoint: path/to/teacher } diff --git a/lighttrain/lab/fork.py b/lighttrain/lab/fork.py index 312f9ed..d75f89b 100644 --- a/lighttrain/lab/fork.py +++ b/lighttrain/lab/fork.py @@ -9,7 +9,7 @@ from lighttrain.lab.fork import fork from lighttrain.config import load_config - cfg = load_config("recipes/pretrain_causal.yaml", ["++optim.lr=1e-4"]) + cfg = load_config("examples/references/recipes/pretrain_causal.yaml", ["++optim.lr=1e-4"]) report = fork(Path("runs/my_exp/run_001/checkpoints/step_1000"), cfg) # → runs/my_fork_exp/20250524-…/ # fork_meta.json ← parent provenance diff --git a/tests/cli/test_app.py b/tests/cli/test_app.py index 7d694b1..6199b59 100644 --- a/tests/cli/test_app.py +++ b/tests/cli/test_app.py @@ -248,7 +248,7 @@ def test_eval_cmd_does_not_crash_on_config_path(runner, tmp_path): # =========================================================================== _REPO = Path(__file__).resolve().parents[2] -_PROFILES = _REPO / "recipes" / "pretrain_causal.yaml" # model: + model_profiles: +_PROFILES = _REPO / "examples" / "references" / "recipes" / "pretrain_causal.yaml" # model: + model_profiles: def _write_models_set_recipe(tmp_path: Path) -> Path: diff --git a/tests/cli/test_model_build_paths.py b/tests/cli/test_model_build_paths.py index 0eb98f0..709158f 100644 --- a/tests/cli/test_model_build_paths.py +++ b/tests/cli/test_model_build_paths.py @@ -20,8 +20,8 @@ from lighttrain.config._models import build_primary_model, normalize_model_set REPO = Path(__file__).resolve().parents[2] -PROFILES = REPO / "recipes" / "pretrain_causal.yaml" # model: + model_profiles: -MODELS_SET = REPO / "recipes" / "online_distill_demo.yaml" # explicit models: set +PROFILES = REPO / "examples" / "references" / "recipes" / "pretrain_causal.yaml" # model: + model_profiles: +MODELS_SET = REPO / "examples" / "references" / "recipes" / "online_distill_demo.yaml" # explicit models: set pytestmark = pytest.mark.skipif( not (PROFILES.exists() and MODELS_SET.exists()), diff --git a/tests/cli/test_runtime.py b/tests/cli/test_runtime.py index 4ffda71..247b1cd 100644 --- a/tests/cli/test_runtime.py +++ b/tests/cli/test_runtime.py @@ -211,7 +211,7 @@ def __init__(self, *a, **k): # --------------------------------------------------------------------------- _REPO = Path(__file__).resolve().parent.parent.parent -_RECIPE = _REPO / "recipes" / "pretrain_causal.yaml" +_RECIPE = _REPO / "examples" / "references" / "recipes" / "pretrain_causal.yaml" _BUNDLE_KEYS = { "cfg", "resolved_yaml", "run_dir", "model", "data", "optimizer", "scheduler", diff --git a/tests/cli/test_runtime_cov.py b/tests/cli/test_runtime_cov.py index 0c958b0..2629df1 100644 --- a/tests/cli/test_runtime_cov.py +++ b/tests/cli/test_runtime_cov.py @@ -81,8 +81,8 @@ # --------------------------------------------------------------------------- _REPO = Path(__file__).resolve().parent.parent.parent -_PRETRAIN_RECIPE = _REPO / "recipes" / "pretrain_causal.yaml" -_SFT_RECIPE = _REPO / "recipes" / "sft_chat.yaml" +_PRETRAIN_RECIPE = _REPO / "examples" / "references" / "recipes" / "pretrain_causal.yaml" +_SFT_RECIPE = _REPO / "examples" / "references" / "recipes" / "sft_chat.yaml" # Import all components once so the registry is populated. import_all_components() diff --git a/tests/config/test_all_recipes_loadable.py b/tests/config/test_all_recipes_loadable.py index b6cfed6..fa83dc3 100644 --- a/tests/config/test_all_recipes_loadable.py +++ b/tests/config/test_all_recipes_loadable.py @@ -22,10 +22,10 @@ from lighttrain.config._resolver import select_model_spec _ROOT = Path(__file__).resolve().parents[2] -# Distributed/sweep overlays now live alongside the rest under recipes/ (they +# Distributed/sweep overlays now live alongside the rest under examples/references/recipes/ (they # were moved out of the old distributed-recipes location back when the bundled # extensions package was renamed to lighttrain.builtin_plugins). -_RECIPES = sorted((_ROOT / "recipes").glob("*.yaml")) +_RECIPES = sorted((_ROOT / "examples" / "references" / "recipes").glob("*.yaml")) def _ids(p: Path) -> str: diff --git a/tests/config/test_models_set_desugar.py b/tests/config/test_models_set_desugar.py index a7b4b8c..aa30ca1 100644 --- a/tests/config/test_models_set_desugar.py +++ b/tests/config/test_models_set_desugar.py @@ -15,7 +15,7 @@ import yaml REPO = Path(__file__).resolve().parent.parent.parent -RECIPE = REPO / "recipes" / "pretrain_causal.yaml" +RECIPE = REPO / "examples" / "references" / "recipes" / "pretrain_causal.yaml" def _losses_for(recipe_path: Path, run_root: Path) -> list[float]: diff --git a/tests/recipes/test_image_cls.py b/tests/recipes/test_image_cls.py index 90cdb30..9587fa3 100644 --- a/tests/recipes/test_image_cls.py +++ b/tests/recipes/test_image_cls.py @@ -15,7 +15,7 @@ from lighttrain.cli._runtime import setup_run_from_config -RECIPE = Path("recipes/image_cls.yaml") +RECIPE = Path("examples/references/recipes/image_cls.yaml") @pytest.mark.skipif(not RECIPE.exists(), reason="image_cls recipe missing") diff --git a/tests/recipes/test_r12.py b/tests/recipes/test_r12.py index e264313..a385d13 100644 --- a/tests/recipes/test_r12.py +++ b/tests/recipes/test_r12.py @@ -14,7 +14,7 @@ import lighttrain.builtin_plugins.layer_offload # noqa: F401 from lighttrain.cli._runtime import setup_run_from_config -RECIPE = Path("recipes/offload_fullparam.yaml") +RECIPE = Path("examples/references/recipes/offload_fullparam.yaml") @pytest.mark.skipif(not RECIPE.exists(), reason="R12 recipe missing") diff --git a/tests/recipes/test_r13.py b/tests/recipes/test_r13.py index 90ec77d..6bcafa7 100644 --- a/tests/recipes/test_r13.py +++ b/tests/recipes/test_r13.py @@ -16,7 +16,7 @@ # Force eager registration of frontier plug-ins. import lighttrain.builtin_plugins.quant # noqa: F401 -_RECIPE = Path("recipes/qlora.yaml") +_RECIPE = Path("examples/references/recipes/qlora.yaml") _HAS_BNB = False try: import bitsandbytes # noqa: F401 diff --git a/tests/recipes/test_r4_r6.py b/tests/recipes/test_r4_r6.py index 8f31ad6..da7c7d5 100644 --- a/tests/recipes/test_r4_r6.py +++ b/tests/recipes/test_r4_r6.py @@ -16,7 +16,7 @@ import yaml -_RECIPES = Path(__file__).parent.parent.parent / "recipes" +_RECIPES = Path(__file__).parent.parent.parent / "examples" / "references" / "recipes" def _load(name: str) -> dict: diff --git a/tests/recipes/test_smoke.py b/tests/recipes/test_smoke.py index a103b54..93e97f9 100644 --- a/tests/recipes/test_smoke.py +++ b/tests/recipes/test_smoke.py @@ -18,7 +18,7 @@ def test_pretrain_causal_config_loads(): """R1 smoke: config parses cleanly and required keys are present.""" - cfg = load_config(REPO / "recipes" / "pretrain_causal.yaml") + cfg = load_config(REPO / "examples" / "references" / "recipes" / "pretrain_causal.yaml") assert cfg is not None # Basic structure expected by the trainer assert hasattr(cfg, "model") or (isinstance(cfg, dict) and "model" in cfg) @@ -26,7 +26,7 @@ def test_pretrain_causal_config_loads(): def test_sft_chat_dry_run(): - bundle = build_prep_runner(REPO / "recipes" / "sft_chat.yaml") + bundle = build_prep_runner(REPO / "examples" / "references" / "recipes" / "sft_chat.yaml") plan = bundle["runner"].dry_run() names = [p.name for p in plan] assert "raw" in names @@ -37,7 +37,7 @@ def test_sft_chat_dry_run(): def test_vlm_sft_dry_run(): - bundle = build_prep_runner(REPO / "recipes" / "vlm_sft.yaml") + bundle = build_prep_runner(REPO / "examples" / "references" / "recipes" / "vlm_sft.yaml") plan = bundle["runner"].dry_run() names = [p.name for p in plan] assert "train_data" in names @@ -45,12 +45,12 @@ def test_vlm_sft_dry_run(): def test_sft_chat_run_then_replay(tmp_path: Path): bundle = build_prep_runner( - REPO / "recipes" / "sft_chat.yaml", + REPO / "examples" / "references" / "recipes" / "sft_chat.yaml", store_root=tmp_path / "prep", ) bundle["runner"].run() bundle2 = build_prep_runner( - REPO / "recipes" / "sft_chat.yaml", + REPO / "examples" / "references" / "recipes" / "sft_chat.yaml", store_root=tmp_path / "prep", ) plan2 = bundle2["runner"].plan() @@ -60,6 +60,6 @@ def test_sft_chat_run_then_replay(tmp_path: Path): @pytest.mark.heavy def test_sft_chat_hf_dry_run(): """HF tokenizer recipe — heavy because of the model download.""" - bundle = build_prep_runner(REPO / "recipes" / "sft_chat_hf.yaml") + bundle = build_prep_runner(REPO / "examples" / "references" / "recipes" / "sft_chat_hf.yaml") plan = bundle["runner"].dry_run() assert any(p.kind == "tokenize" for p in plan) diff --git a/tests/regression/test_gap_report_fixes.py b/tests/regression/test_gap_report_fixes.py index e166b36..25bb119 100644 --- a/tests/regression/test_gap_report_fixes.py +++ b/tests/regression/test_gap_report_fixes.py @@ -342,7 +342,7 @@ def test_demo_recipe_runs(recipe, tmp_path): from lighttrain.cli._runtime import setup_run_from_config cfg = load_config( - f"recipes/{recipe}.yaml", + f"examples/references/recipes/{recipe}.yaml", overrides=[ f"run_root={tmp_path}", "trainer.max_steps=2", @@ -364,7 +364,7 @@ def test_jepa_recipe_advances_target_encoder(tmp_path): from lighttrain.cli._runtime import setup_run_from_config cfg = load_config( - "recipes/jepa.yaml", + "examples/references/recipes/jepa.yaml", overrides=[f"run_root={tmp_path}", "trainer.max_steps=3", "trainer.ckpt_every=0", "trainer.log_every=1"], ) @@ -383,7 +383,7 @@ def test_rwkv_recipe_wires_arch_profile_object(tmp_path): from lighttrain.cli._runtime import setup_run_from_config cfg = load_config( - "recipes/pretrain_rwkv.yaml", + "examples/references/recipes/pretrain_rwkv.yaml", overrides=[f"run_root={tmp_path}", "trainer.max_steps=3", "trainer.ckpt_every=0", "trainer.log_every=1"], ) @@ -401,7 +401,7 @@ def test_rwkv_recipe_wires_arch_profile_object(tmp_path): def test_x_labels_one_hot_matches_mlp_toy_top_for_pcn_clamp(): """M4: x_labels emits (B, output_dim) one-hot so the PCN supervised clamp (labels.shape == top_activation.shape) actually fires.""" - from examples.lab_components import MLPToy, XLabelsCollator + from examples.references.lab_components import MLPToy, XLabelsCollator coll = XLabelsCollator(num_classes=2) batch = coll([{"x": torch.randn(16), "label": 1}, {"x": torch.randn(16), "label": 0}]) diff --git a/tests/trainers/test_ppo_grpo_wiring.py b/tests/trainers/test_ppo_grpo_wiring.py index 42146d3..820fe76 100644 --- a/tests/trainers/test_ppo_grpo_wiring.py +++ b/tests/trainers/test_ppo_grpo_wiring.py @@ -20,7 +20,7 @@ import pytest import torch -_RECIPES = Path(__file__).resolve().parents[2] / "recipes" +_RECIPES = Path(__file__).resolve().parents[2] / "examples" / "references" / "recipes" _FIXTURES = Path(__file__).resolve().parents[1] / "fixtures" diff --git a/tests/trainers/test_pretrain.py b/tests/trainers/test_pretrain.py index 3227bbb..c917a5d 100644 --- a/tests/trainers/test_pretrain.py +++ b/tests/trainers/test_pretrain.py @@ -345,7 +345,7 @@ def test_pretrain_fit_raises_when_optimizer_is_none(): from pathlib import Path # noqa: E402 _REPO_ROOT = Path(__file__).resolve().parents[2] -_PRETRAIN_RECIPE = _REPO_ROOT / "recipes" / "pretrain_causal.yaml" +_PRETRAIN_RECIPE = _REPO_ROOT / "examples" / "references" / "recipes" / "pretrain_causal.yaml" def _loss_windows(jsonl_path: Path, fraction: float = 0.25) -> tuple[float, float]: From e9d8e2ae87406b852d8b62b09f09d57b4c44c8c7 Mon Sep 17 00:00:00 2001 From: CanGeng <2441506707@qq.com> Date: Sat, 27 Jun 2026 09:38:26 +0800 Subject: [PATCH 2/2] =?UTF-8?q?docs(changelog):=20v0.5.3=20=E2=80=94=20rec?= =?UTF-8?q?ipes=E2=86=92examples/references=20relocation;=20bump=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR1 of 2. Pure relocation, no runtime behavior change. nanoGPT/MiniMind localized ports land at examples/ top level in PR2. CanGeng --- docs/changelog/v0/v0.5/v0.5.3.md | 37 ++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 docs/changelog/v0/v0.5/v0.5.3.md diff --git a/docs/changelog/v0/v0.5/v0.5.3.md b/docs/changelog/v0/v0.5/v0.5.3.md new file mode 100644 index 0000000..c02a80e --- /dev/null +++ b/docs/changelog/v0/v0.5/v0.5.3.md @@ -0,0 +1,37 @@ +# v0.5.3 + +> **`recipes/` 并入 `examples/`(PR1 / 2,纯重定位)**:把仓库根的 `recipes/` 与 `examples/` 合并到统一的 `examples/references/` 树下——YAML 配方移入 `examples/references/recipes/`,程序化 API 示例脚本移入 `examples/references/`。保留「recipe」概念词(CLI、registry、测试分组名不变),仅改文件路径。零运行时行为变化,纯文件搬家 + 引用路径更新;注册表 **33 category / 134 entries** 不变。知名仓库的本地化移植(nanoGPT / MiniMind 等)将作为 PR2 落在 `examples/` 顶层,本轮不含。 + +## 动机 + +旧布局把可运行入口拆成两处:`recipes/*.yaml`(CLI 配方)与 `examples/*.py`(程序化示例),二者双向耦合——示例 `load_config("recipes/X.yaml")`,而 5 个演示配方又经 `user_modules:` 反向 import `examples/*.py` 里的自定义组件。合并到一棵 `examples/references/` 树后,两个方向的引用都落在同一子树内,概念更清晰,也为顶层放「知名仓库忠实移植」腾出位置。 + +## 新布局 + +``` +examples/ + references/ + recipes/ # 全部 YAML 配方(原 recipes/,29 个) + pretrain_causal.yaml grpo.yaml ddp.yaml ... + pretrain_causal.py grpo.py ... # 程序化示例(原 examples/,23 个) + lab_components.py vision_components.py online_distill.py # 被配方 user_modules 加载的共享组件 + README.md + README.md # 顶层导航(知名仓库移植 → PR2) +``` + +- **canonical CLI 路径**:`lighttrain train -c examples/references/recipes/pretrain_causal.yaml`。 +- 共享组件 `lab_components.py`(被 ff_demo / mezo_sft / jepa / diffusion_eps / pcn_demo **5 个**配方共享)平铺在 `references/` 根,5 个配方都能引用——这也是不采用「一例一子目录」的原因(共享件无法同时住进 5 个子目录)。 + +## 改动范围(机械、可逐一断言) + +- **物理移动(`git mv` 保历史)**:`recipes/*.yaml` → `examples/references/recipes/`;`examples/*.py` → `examples/references/`;`examples/README.md` → `examples/references/README.md`;新建顶层 `examples/README.md`;删空目录 `recipes/`。 +- **路径引用更新**:`recipes/` → `examples/references/recipes/`(配方注释、示例脚本的 `load_config` / docstring、README ×2、docs 的 concepts/extending/operations 共 8 篇、生产 docstring 与 CLI `--help` epilog 7 处、`scripts/rt.sh`、测试中的字符串/路径段形式);配方 `user_modules:` 与点式 import 中 `examples/{lab_components,vision_components,online_distill}` → `examples/references/...`。 +- **不改**:`docs/changelog/**`(历史记录,point-in-time 保留旧路径);「recipe」概念词与 `tests/recipes/` 测试目录名。 + +## 验证 + +- `pytest`:**4491 passed / 7 skipped / 0 failed**(路径敏感面:`tests/recipes/`、`test_all_recipes_loadable`、CLI、regression demo-recipe e2e 全绿)。 +- `ruff check .`:全净。 +- `mypy lighttrain tests`:575 文件零 error。 +- CLI 冒烟:`lighttrain train -c examples/references/recipes/pretrain_causal.yaml --print-config` 通。 +- 残留扫描:跟踪文件中除 `docs/changelog/**` 与 OOM 报告测试的任意假路径外,无残留旧 `recipes/` 引用。 diff --git a/pyproject.toml b/pyproject.toml index d9628ad..2e73ba6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "lighttrain" -version = "0.5.2" +version = "0.5.3" description = "PyTorch training framework for research labs" readme = "README.md" license = { text = "MIT" }