Initial K3 snapshot: 0.5B KDA/MLA/MoE train path

Standalone tree split from LLMRL/projects/kda. Includes Triton dt_bias
backward fix, train_k3 --preset 0.5b, SFT, Docker runtime, and tests.
This commit is contained in:
dela
2026-08-25 14:43:17 +08:00
commit 584f7e9e73
140 changed files with 21592 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
"""Default container command: print usage and refuse to start a silent toy run."""
from __future__ import annotations
HELP = """kda image: one GPU runtime for train / monitor / eval.
Do not docker run without a command — toy overfit is not the default.
Volumes (host → container):
./ckpts → /workspace/kda/ckpts
pretrain corpus → /data/pretrain (ro)
SFT bitext → /data/sft (ro)
frozen eval → /data/eval (ro)
HF tokenizer cache → /cache/huggingface
SWANLAB_API_KEY via -e (never COPY into the image)
Examples:
docker run --rm --gpus all kda:<tag> python train.py
docker run --rm --gpus all -e SWANLAB_API_KEY \\
-v "$PWD/ckpts:/workspace/kda/ckpts" \\
kda:<tag> python train_k3.py --preset toy --attnres off
docker run --rm --gpus all kda:<tag> swanlab ping
docker run --rm --gpus all \\
-v "$PWD/ckpts:/workspace/kda/ckpts" -v "$PWD/data/eval:/data/eval:ro" \\
kda:<tag> python -m kda.training.eval_mt \\
--ckpt /workspace/kda/ckpts/k3_wiki.pt \\
--src /data/eval/zh2en.src.txt --ref /data/eval/zh2en.ref.txt \\
--target-lang en
docker run --rm --gpus all \\
-v "$PWD/ckpts:/workspace/kda/ckpts" -v "$PWD/data/sft:/data/sft:ro" \\
kda:<tag> python train_sft.py --ckpt /workspace/kda/ckpts/k3_wiki.pt \\
--data /data/sft/toy.jsonl
docker run --rm --gpus all kda:<tag> python -m pytest -q
"""
def main() -> None:
print(HELP)
raise SystemExit(2)
if __name__ == "__main__":
main()
+61
View File
@@ -0,0 +1,61 @@
"""Export FLORES-200 zh↔en into line-aligned src/ref files for eval_mt.
Corpus is not committed. Typical:
uv run python scripts/export_flores.py --out data/eval
"""
from __future__ import annotations
import argparse
from pathlib import Path
def _write(path: Path, lines: list[str]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def main() -> None:
p = argparse.ArgumentParser(description=__doc__)
p.add_argument("--out", default="data/eval")
p.add_argument("--split", default="devtest", choices=["dev", "devtest"])
args = p.parse_args()
from datasets import load_dataset
ds = None
err: Exception | None = None
for config in ("eng_Latn-zho_Hans", "default"):
try:
ds = load_dataset("facebook/flores", config, split=args.split)
break
except Exception as exc: # noqa: BLE001 — try the next config name
err = exc
if ds is None:
raise SystemExit(f"could not load facebook/flores ({err})")
cols = set(ds.column_names)
en_key = next(
(c for c in ("sentence_eng_Latn", "eng_Latn", "sentence_en") if c in cols),
None,
)
zh_key = next(
(c for c in ("sentence_zho_Hans", "zho_Hans", "sentence_zh") if c in cols),
None,
)
if en_key is None or zh_key is None:
raise SystemExit(f"FLORES columns not found: {sorted(cols)}")
en = [row[en_key].strip() for row in ds]
zh = [row[zh_key].strip() for row in ds]
out = Path(args.out)
_write(out / "flores.zh2en.src.txt", zh)
_write(out / "flores.zh2en.ref.txt", en)
_write(out / "flores.en2zh.src.txt", en)
_write(out / "flores.en2zh.ref.txt", zh)
print(f"wrote {len(zh)} pairs under {out}/flores.*.txt")
if __name__ == "__main__":
main()