Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ NPU, offline, and managed/external-service variants, is in
| `examples/configs/qwen3.5-4b-dflash-online-npu.yaml` | Disaggregated NPU SGLang capture | DFlash |
| `examples/configs/qwen3.5-4b-dflash-disaggregated-npu.yaml` | Managed local NPU full stack | DFlash |
| `examples/configs/qwen3.5-4b-domino-online-npu.yaml` | Disaggregated NPU SGLang capture | Domino |
| `examples/configs/qwen3.5-4b-domino-disaggregated-npu.yaml` | Managed local NPU full stack | Domino |

Online configs point `data.train_data_path` at raw conversation data. Offline
configs expect strategy-specific feature checkpoints in
Expand Down
62 changes: 62 additions & 0 deletions examples/configs/qwen3.5-4b-domino-disaggregated-npu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Single-node managed full stack for Ascend NPU: one `specforge train` command
# owns Mooncake, one patched SGLang capture server (device 0), and a 14-rank
# trainer (devices 2-15). Device ordinals are injected via
# ASCEND_RT_VISIBLE_DEVICES on Ascend hosts.
model:
target_model_path: "Qwen/Qwen3.5-4B"
draft_model_config: "configs/qwen3.5-4b-domino.json"
target_backend: sglang
trust_remote_code: true
embedding_key: "model.language_model.embed_tokens.weight"
torch_dtype: "bfloat16"
sglang_attention_backend: ascend
data:
train_data_path: "./cache/dataset/train_regen.jsonl"
max_length: 1024
chat_template: "qwen3.5"
build_dataset_num_proc: 32
cache_dir: "./cache"
training:
strategy: "domino"
num_epochs: 10
batch_size: 1
accumulation_steps: 4
learning_rate: 0.0006
warmup_ratio: 0.04
max_grad_norm: 1
attention_backend: "sdpa"
num_anchors: 16
loss_decay_gamma: 7
lambda_base_start: 1
lambda_base_decay_ratio: 1
save_interval: 3000
log_interval: 50
dist_timeout: 30
seed: 42
tracking:
report_to: "tensorboard"
run_id: "qwen3.5-4b-domino-npu-managed"
output_dir: "./outputs/qwen3.5-4b-domino-npu-managed"

deployment:
mode: disaggregated
trainer:
nnodes: 1
nproc_per_node: 14
disaggregated:
control_dir: outputs/qwen3.5-4b-domino-npu-managed/control
consumer_state_dir: outputs/qwen3.5-4b-domino-npu-managed/consumer-state
backend: mooncake
managed_local:
# 16-card A3 layout: capture server owns device 0, trainer owns 2-15.
# On 8-card hosts use devices 1-7 with trainer.nproc_per_node: 7.
trainer_cuda_visible_devices:
["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"]
mooncake:
# Host segment mounted by the capture-server sink for feature storage.
# 16 GiB fits a 64GB-card host next to the target model and KV cache.
global_segment_size_bytes: 17179869184
capture_servers:
- port: 30000
cuda_visible_devices: ["0"]
tp_size: 1
36 changes: 35 additions & 1 deletion tests/test_config/test_launch_topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"qwen3.5-35b-a3b-eagle3-online.yaml": 2,
"qwen3.5-4b-dflash-online-npu.yaml": 8,
"qwen3.5-4b-dflash-disaggregated-npu.yaml": 14,
"qwen3.5-4b-domino-disaggregated-npu.yaml": 14,
"qwen3.5-4b-domino-online-npu.yaml": 8,
"qwen3.6-27b-dflash-disaggregated.yaml": 2,
"qwen3.6-27b-dflash-1server-dp2-disaggregated.yaml": 2,
Expand Down Expand Up @@ -261,6 +262,39 @@
],
},
},
"qwen3.5-4b-domino-disaggregated-npu.yaml": {
"control_dir": "outputs/qwen3.5-4b-domino-npu-managed/control",
"consumer_state_dir": "outputs/qwen3.5-4b-domino-npu-managed/consumer-state",
"backend": "mooncake",
"managed_local": {
"trainer_cuda_visible_devices": [
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
"13",
"14",
"15",
],
"mooncake": {
"global_segment_size_bytes": 17179869184,
},
"capture_servers": [
{
"port": 30000,
"cuda_visible_devices": ["0"],
"tp_size": 1,
}
],
},
},
"qwen3.6-27b-dflash-disaggregated.yaml": {
"control_dir": "outputs/qwen3.6-27b-dflash-disaggregated/control",
"backend": "mooncake",
Expand Down Expand Up @@ -347,7 +381,7 @@ def _recipes() -> dict[str, Path]:
class ExampleLaunchTopologyTest(unittest.TestCase):
def test_every_recipe_has_the_explicit_golden_topology(self):
recipes = _recipes()
self.assertEqual(len(EXPECTED_NPROC_PER_NODE), 65)
self.assertEqual(len(EXPECTED_NPROC_PER_NODE), 66)
self.assertEqual(set(recipes), set(EXPECTED_NPROC_PER_NODE))

for filename, nproc_per_node in EXPECTED_NPROC_PER_NODE.items():
Expand Down
2 changes: 1 addition & 1 deletion tests/test_config/test_unified_feature_reachability.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def test_all_example_configs_validate_through_the_typed_entry(self):
for path in EXAMPLE_CONFIG_DIR.glob("*.yaml")
if not path.name.startswith(".")
)
self.assertEqual(len(paths), 65)
self.assertEqual(len(paths), 66)

resolved_runs = {
path.name: resolve_run(Config.from_file(str(path))) for path in paths
Expand Down
Loading