Jelajahi Sumber

fix(deepseek): align parameters with working system

Complete parameter alignment between the deepseek-v4-flash recipe and
the working sparkrun-based vLLM launch on the same cluster.

### Recipe args fixed:
- --max-num-seqs: 6 → 8 (match working)
- --compilation-config: broken TOML strings → clean literal strings
- --load-format: single arg with space → two separate args
- --default-chat-template-kwargs: dotted keys + extras → JSON dict
  (removed reasoning_effort, reasoning-config — not in working)
- Added RAY memory env vars to [env]

### Cluster-driven env vars added (docker/mod.rs):
- MN_IF_NAME, UCX_NET_DEVICES, OMPI_MCA_btl_tcp_if_include
  from nccl.socket_ifname
- RAY_NODE_IP_ADDRESS, RAY_OVERRIDE_NODE_IP_ADDRESS
  from node.ib_ip (ray backend only)

### Removed defaults that working system doesn't use:
- NCCL_CUMEM_ENABLE=0 (disables CUDA memory pool, may worsen
  memory pressure during compilation)
- NCCL_CROSS_NIC=1 (unnecessary on single-socket DGX Spark)
Alexander Korolev 4 bulan lalu
induk
melakukan
d9c3f845c2
3 mengubah file dengan 36 tambahan dan 19 penghapusan
  1. 14 9
      recipes/deepseek-v4-flash/recipe.toml
  2. 10 2
      src/docker/mod.rs
  3. 12 8
      src/docker/tests.rs

+ 14 - 9
recipes/deepseek-v4-flash/recipe.toml

@@ -1,6 +1,6 @@
 engine = "vllm"
 name = "DeepSeek V4 Flash (vLLM)"
-docker_image = "aidendle94/sparkrun-vllm-ds4-gb10:production-ready"
+docker_image = "aidendle94/sparkrun-vllm-ds4-gb10:production-v2"
 model = "deepseek-ai/DeepSeek-V4-Flash"
 required_nodes = 2
 tensor_parallel_size = 2
@@ -16,27 +16,32 @@ entrypoint = ["vllm", "serve"]
 args = [
     "--kv-cache-dtype", "fp8",
     "--block-size", "256",
-    "--max-model-len", "1048576",
-    "--max-num-seqs", "6",
+    "--max-model-len", "524288",
+    "--max-num-seqs", "8",
     "--max-num-batched-tokens", "8192",
-    "--gpu-memory-utilization", "0.82",
+    "--enable-chunked-prefill",
+    "--gpu-memory-utilization", "0.85",
+    "--compilation-config", '{"cudagraph_mode":"FULL_AND_PIECEWISE","custom_ops":["all"]}',
     "--enable-prefix-caching",
+    "--load-format", "safetensors",
     "--speculative-config", '{"method":"mtp","num_speculative_tokens":2}',
     "--tokenizer-mode", "deepseek_v4",
     "--tool-call-parser", "deepseek_v4",
     "--enable-auto-tool-choice",
     "--reasoning-parser", "deepseek_v4",
-    "--reasoning-config", '{"reasoning_parser":"deepseek_v4","reasoning_start_str":"","reasoning_end_str":""}',
-    "--default-chat-template-kwargs.thinking", "true",
-    "--default-chat-template-kwargs.reasoning_effort", "high",
+    "--default-chat-template-kwargs", '{"thinking":true,"preserve_thinking":true}',
     "--enable-flashinfer-autotune",
     "--trust-remote-code",
     "--served-model-name", "deepseek-v4-flash", "default",
 ]
 
+# --distributed-executor-backend mp
+
 [env]
-# HuggingFace / cache config
-VLLM_CACHE_ROOT = "/cache/huggingface/vllm-cache"
+# Ray memory management — prevents OOM during cudagraph compilation
+RAY_memory_monitor_refresh_ms = "0"
+RAY_num_prestart_python_workers = "0"
+RAY_object_store_memory = "1073741824"
 
 # vLLM features for DeepSeek V4 on Blackwell (GB10 / sm_120)
 VLLM_ALLOW_LONG_MAX_MODEL_LEN = "1"

+ 10 - 2
src/docker/mod.rs

@@ -389,12 +389,18 @@ fn build_docker_command(
         cmd.push(format!("-e VLLM_HOST_IP={}", node.ib_ip));
     }
 
+    // Network interface env vars from cluster NCCL config
+    cmd.push(format!("-e MN_IF_NAME={}", nccl.socket_ifname));
+    cmd.push(format!("-e UCX_NET_DEVICES={}", nccl.socket_ifname));
+    cmd.push(format!(
+        "-e OMPI_MCA_btl_tcp_if_include={}",
+        nccl.socket_ifname
+    ));
+
     // Default cluster env (recipe env below overrides these if duplicated)
-    cmd.push("-e NCCL_CUMEM_ENABLE=0".to_string());
     cmd.push("-e OMP_NUM_THREADS=4".to_string());
     cmd.push("-e NCCL_IGNORE_CPU_AFFINITY=1".to_string());
     cmd.push("-e NCCL_NET=IB".to_string());
-    cmd.push("-e NCCL_CROSS_NIC=1".to_string());
     cmd.push("-e NCCL_DEBUG=WARN".to_string());
 
     for (k, v) in &recipe.env {
@@ -409,6 +415,8 @@ fn build_docker_command(
     if recipe.distributed_backend == "ray" {
         cmd.push(format!("-e RAY_ADDRESS={}:6379", cluster.master_ib_ip));
         cmd.push(format!("-e RAY_PORT={}", recipe.port));
+        cmd.push(format!("-e RAY_NODE_IP_ADDRESS={}", node.ib_ip));
+        cmd.push(format!("-e RAY_OVERRIDE_NODE_IP_ADDRESS={}", node.ib_ip));
     }
     cmd.push(recipe.docker_image.clone());
     if !recipe.entrypoint.is_empty() {

+ 12 - 8
src/docker/tests.rs

@@ -115,10 +115,6 @@ fn mp() {
     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 GLOO_SOCKET_IFNAME=e"),
         "default GLOO_SOCKET_IFNAME missing"
@@ -136,14 +132,22 @@ fn mp() {
         "default NCCL_IGNORE_CPU_AFFINITY missing"
     );
     assert!(cmd.contains("-e NCCL_NET=IB"), "default NCCL_NET missing");
-    assert!(
-        cmd.contains("-e NCCL_CROSS_NIC=1"),
-        "default NCCL_CROSS_NIC missing"
-    );
     assert!(
         cmd.contains("-e NCCL_DEBUG=WARN"),
         "default NCCL_DEBUG missing"
     );
+    assert!(
+        cmd.contains("-e MN_IF_NAME=e"),
+        "cluster MN_IF_NAME missing"
+    );
+    assert!(
+        cmd.contains("-e UCX_NET_DEVICES=e"),
+        "cluster UCX_NET_DEVICES missing"
+    );
+    assert!(
+        cmd.contains("-e OMPI_MCA_btl_tcp_if_include=e"),
+        "cluster OMPI_MCA_btl_tcp_if_include missing"
+    );
     // Head node: no --headless
     assert!(!cmd.contains("--headless"));
 }