|
|
@@ -63,6 +63,7 @@ fn run(recipe: &Recipe, node: &Node, head: bool) -> String {
|
|
|
2,
|
|
|
"/home/user/.cache/huggingface",
|
|
|
false,
|
|
|
+ 25000,
|
|
|
)
|
|
|
.join(" ")
|
|
|
}
|
|
|
@@ -79,6 +80,7 @@ fn run_keep(recipe: &Recipe, node: &Node, head: bool) -> String {
|
|
|
2,
|
|
|
"/home/user/.cache/huggingface",
|
|
|
true,
|
|
|
+ 25000,
|
|
|
)
|
|
|
.join(" ")
|
|
|
}
|
|
|
@@ -100,9 +102,24 @@ fn mp() {
|
|
|
assert!(cmd.contains("--nnodes 2"));
|
|
|
assert!(cmd.contains("--node-rank 0"));
|
|
|
assert!(cmd.contains("--master-addr 1"));
|
|
|
+ assert!(cmd.contains("--master-port 25000"));
|
|
|
assert!(cmd.contains("--distributed-executor-backend mp"));
|
|
|
assert!(!cmd.contains("RAY_ADDRESS"));
|
|
|
assert!(cmd.contains("--rm"), "default --rm should be present");
|
|
|
+ // New: defaults & cluster env
|
|
|
+ assert!(cmd.contains("--shm-size 10g"), "default shm-size missing");
|
|
|
+ assert!(cmd.contains("--ulimit memlock=-1"));
|
|
|
+ assert!(cmd.contains("--ulimit stack=67108864"));
|
|
|
+ assert!(
|
|
|
+ cmd.contains("-e NCCL_CUMEM_ENABLE=0"),
|
|
|
+ "default NCCL_CUMEM_ENABLE missing"
|
|
|
+ );
|
|
|
+ assert!(
|
|
|
+ cmd.contains("-e OMP_NUM_THREADS=4"),
|
|
|
+ "default OMP_NUM_THREADS missing"
|
|
|
+ );
|
|
|
+ // Head node: no --headless
|
|
|
+ assert!(!cmd.contains("--headless"));
|
|
|
}
|
|
|
|
|
|
#[test]
|
|
|
@@ -112,6 +129,8 @@ fn worker_no_port() {
|
|
|
assert!(cmd.contains("--node-rank 1"));
|
|
|
assert!(cmd.contains("--label sm121.rank=1"));
|
|
|
assert!(cmd.contains("--name sm121_r_1"));
|
|
|
+ // New: vLLM workers run --headless
|
|
|
+ assert!(cmd.contains("--headless"), "vLLM worker should be headless");
|
|
|
}
|
|
|
|
|
|
#[test]
|
|
|
@@ -177,6 +196,7 @@ fn srun(recipe: &Recipe, node: &Node, head: bool) -> String {
|
|
|
4,
|
|
|
"/home/user/.cache/huggingface",
|
|
|
false,
|
|
|
+ 25000,
|
|
|
)
|
|
|
.join(" ")
|
|
|
}
|
|
|
@@ -245,3 +265,47 @@ fn keep_disables_rm() {
|
|
|
assert!(cmd.contains("-e HF_HOME=/cache/huggingface"));
|
|
|
assert!(cmd.contains("-v /home/user/.cache/huggingface:/cache/huggingface"));
|
|
|
}
|
|
|
+
|
|
|
+#[test]
|
|
|
+fn recipe_env_overrides_cluster_defaults() {
|
|
|
+ // Recipe-level env should win over the defaults we inject.
|
|
|
+ let mut r = trec();
|
|
|
+ r.env.insert("NCCL_CUMEM_ENABLE".into(), "1".into());
|
|
|
+ r.env.insert("OMP_NUM_THREADS".into(), "16".into());
|
|
|
+ let cmd = run(&r, &tcls().nodes[0], true);
|
|
|
+ // Docker uses the last -e for duplicate keys, so recipe values come after.
|
|
|
+ // rfind returns the last occurrence, which should be the recipe override.
|
|
|
+ let cumem_pos = cmd.rfind("NCCL_CUMEM_ENABLE=").unwrap();
|
|
|
+ assert!(
|
|
|
+ cmd[cumem_pos..].starts_with("NCCL_CUMEM_ENABLE=1"),
|
|
|
+ "recipe override should be last: slice starts at {}",
|
|
|
+ cumem_pos
|
|
|
+ );
|
|
|
+ let omp_pos = cmd.rfind("OMP_NUM_THREADS=").unwrap();
|
|
|
+ assert!(
|
|
|
+ cmd[omp_pos..].starts_with("OMP_NUM_THREADS=16"),
|
|
|
+ "recipe override should be last"
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+#[test]
|
|
|
+fn custom_init_port() {
|
|
|
+ // Non-default init_port should propagate to vLLM master-port and
|
|
|
+ // SGLang dist-init-addr.
|
|
|
+ let cmd = build_docker_command(
|
|
|
+ &tcls(),
|
|
|
+ &tnccl(),
|
|
|
+ &trec(),
|
|
|
+ "r",
|
|
|
+ &tcls().nodes[0],
|
|
|
+ true,
|
|
|
+ 2,
|
|
|
+ 2,
|
|
|
+ "/home/user/.cache/huggingface",
|
|
|
+ false,
|
|
|
+ 29500,
|
|
|
+ )
|
|
|
+ .join(" ");
|
|
|
+ assert!(cmd.contains("--master-port 29500"));
|
|
|
+ assert!(cmd.contains("--master-addr 1"));
|
|
|
+}
|