LordNeel commited on
Commit
8c958bc
·
verified ·
1 Parent(s): efbb6db

Add AGENTS.md — end-to-end runbook for AI agents to set up + serve this model

Browse files
Files changed (1) hide show
  1. AGENTS.md +404 -0
AGENTS.md ADDED
@@ -0,0 +1,404 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Agent runbook — set up `LordNeel/DeepSeek-V4-Flash-Acti-MTP-W4A16-FP8` end-to-end
2
+
3
+ **For**: an autonomous code agent (Claude Code, Codex, Cursor, Aider, etc.) running on a fresh-ish Linux box with the right hardware. Stop and ask the human only when explicitly told.
4
+
5
+ **Goal**: a vLLM OpenAI-compatible server on port 8000 serving the MTP-enabled model at the validated 524k profile, with smoke tests passing.
6
+
7
+ ---
8
+
9
+ ## Phase 0 — verify hardware (HARD STOP if not satisfied)
10
+
11
+ Run `nvidia-smi --query-gpu=name,memory.total --format=csv,noheader` and `nvidia-smi topo -m`.
12
+
13
+ Validated SKUs (any of these works without code changes):
14
+ - 2× **RTX PRO 6000 Blackwell Max-Q Workstation Edition** (96 GB ea, sm_120, no NVLink) ← reference platform
15
+ - 2× RTX PRO 6000 Blackwell Server (96 GB ea, sm_120, with NVLink) ← also expected to work
16
+ - 2× DGX Spark / GB10 (sm_121)
17
+ - 8× H200 SXM (sm_90)
18
+
19
+ **Stop and ask the human if any of the following is true**:
20
+ - Fewer than 2 GPUs with ≥ 96 GB each (TP=2 with 524k KV cache won't fit)
21
+ - More than 2 visible GPUs and you'd need to pick which 2 (set `CUDA_VISIBLE_DEVICES` deliberately, don't guess)
22
+ - GPU is on a topology where `nvidia-smi topo -m` reports `SYS` (cross-NUMA) — this can cause more comm overhead; not a blocker but flag it
23
+
24
+ Detect Max-Q-specific quirks: if the GPU name contains "Max-Q" you MUST pass `--disable-custom-all-reduce` later. The serve script already does this.
25
+
26
+ ---
27
+
28
+ ## Phase 1 — system prereqs (no sudo)
29
+
30
+ Working dir: pick `$HOME/dsv4-local` (the reference layout). All paths in this doc assume that.
31
+
32
+ ```bash
33
+ mkdir -p $HOME/dsv4-local
34
+ cd $HOME/dsv4-local
35
+ ```
36
+
37
+ Required:
38
+ - Python 3.12 (system or via miniforge — agent's choice; reference uses miniforge3)
39
+ - Driver: NVIDIA 580.x or newer (check `nvidia-smi`)
40
+ - gcc/g++ 13.x (system) — used as host compiler for nvcc
41
+ - Git, curl, jq, ca-certificates (apt should already have these)
42
+
43
+ Forbidden without explicit human approval:
44
+ - Modifying `/etc`, kernel modules, drivers, or system CUDA
45
+ - Installing system packages with sudo (use conda for CUDA toolkit instead)
46
+ - Touching `/proc/sys/*` or `nvidia-smi -pl`/`-lgc` (those need sudo)
47
+
48
+ ---
49
+
50
+ ## Phase 2 — local CUDA toolkit via conda (no sudo)
51
+
52
+ ```bash
53
+ # 2a. Miniforge3 (only if conda not already available)
54
+ test -x $HOME/dsv4-local/miniforge3/bin/conda || (
55
+ curl -fsSLO https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh
56
+ bash Miniforge3-Linux-x86_64.sh -b -p $HOME/dsv4-local/miniforge3
57
+ )
58
+ $HOME/dsv4-local/miniforge3/bin/conda init bash >/dev/null
59
+
60
+ # 2b. CUDA toolkit 12.9 in a self-contained env
61
+ $HOME/dsv4-local/miniforge3/bin/conda create -y -p $HOME/dsv4-local/conda-cuda \
62
+ -c nvidia -c conda-forge cuda-toolkit=12.9 ccache
63
+
64
+ # 2c. Verify
65
+ $HOME/dsv4-local/conda-cuda/bin/nvcc --version | tail -3
66
+ ```
67
+
68
+ Common gotcha: conda's default put CUDA headers under `targets/x86_64-linux/include/` instead of `include/`. The vLLM build will fail with "Could NOT find CUDA". Fix by symlinking once:
69
+
70
+ ```bash
71
+ CUDA_HOME=$HOME/dsv4-local/conda-cuda
72
+ for f in $(ls $CUDA_HOME/targets/x86_64-linux/include 2>/dev/null); do
73
+ test -e $CUDA_HOME/include/$f || ln -s ../targets/x86_64-linux/include/$f $CUDA_HOME/include/$f
74
+ done
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Phase 3 — Python venv + base deps
80
+
81
+ ```bash
82
+ mkdir -p $HOME/dsv4-local/venvs
83
+ python3.12 -m venv $HOME/dsv4-local/venvs/vllm-dsv4
84
+ source $HOME/dsv4-local/venvs/vllm-dsv4/bin/activate
85
+ python -m pip install --upgrade pip wheel setuptools
86
+ pip install \
87
+ "torch==2.11.0+cu128" --index-url https://download.pytorch.org/whl/cu128
88
+ pip install \
89
+ "transformers==5.8.0" \
90
+ "compressed-tensors==0.15.0.1" \
91
+ "safetensors>=0.7" \
92
+ "huggingface_hub>=1.14" \
93
+ hf_transfer \
94
+ "openai" \
95
+ "rich" \
96
+ "datasets"
97
+ ```
98
+
99
+ (If conda gcc-14 is on PATH, force system gcc/g++ for the upcoming vLLM build:
100
+ `export CC=/usr/bin/gcc CXX=/usr/bin/g++ CUDAHOSTCXX=/usr/bin/g++ NVCC_PREPEND_FLAGS="-ccbin /usr/bin/g++"`.)
101
+
102
+ ---
103
+
104
+ ## Phase 4 — patched vLLM fork
105
+
106
+ ```bash
107
+ mkdir -p $HOME/dsv4-local/src
108
+ cd $HOME/dsv4-local/src
109
+ git clone https://github.com/jasl/vllm.git vllm
110
+ cd vllm
111
+ # Validated pin. This is itself a cherry-pick of neuralmagic/vllm@f910a73 ("support
112
+ # ct quantization" — Kyle Sayers); pinning here means you do NOT need the extra
113
+ # cherry-pick step that older versions of this runbook documented.
114
+ git checkout b158e5001f097b193b4fa8c4fc7bb32bb4e32e9e
115
+
116
+ # pasta-paul's packed_modules_mapping patch (adds the class-level dict on
117
+ # DeepseekV4ForCausalLM that the cherry-pick references but doesn't define).
118
+ curl -fsSL https://raw.githubusercontent.com/pasta-paul/dsv4-flash-w4a16-fp8/main/scripts/patch_v4_packed_mapping.py \
119
+ -o /tmp/patch_packed.py
120
+ python /tmp/patch_packed.py vllm/model_executor/models/deepseek_v4.py
121
+ ```
122
+
123
+ ### Acti's MTP-loader patches (~30 lines, three edits in `vllm/model_executor/models/deepseek_v4_mtp.py`)
124
+
125
+ Apply each of these or you'll hit the six load errors documented in the model card.
126
+
127
+ #### Patch 4a ��� pass `prefix=` to e_proj / h_proj
128
+
129
+ In `class DeepSeekV4MultiTokenPredictorLayer.__init__`, change both ReplicatedLinear constructions:
130
+
131
+ ```python
132
+ self.e_proj = ReplicatedLinear(
133
+ config.hidden_size, config.hidden_size,
134
+ bias=False, return_bias=False,
135
+ quant_config=quant_config,
136
+ prefix=f"{prefix}.e_proj", # <-- ADD THIS
137
+ )
138
+ self.h_proj = ReplicatedLinear(
139
+ config.hidden_size, config.hidden_size,
140
+ bias=False, return_bias=False,
141
+ quant_config=quant_config,
142
+ prefix=f"{prefix}.h_proj", # <-- ADD THIS
143
+ )
144
+ ```
145
+
146
+ #### Patch 4b — `packed_modules_mapping` on `DeepSeekV4MTP`
147
+
148
+ Add a class attribute right above `__init__`:
149
+
150
+ ```python
151
+ class DeepSeekV4MTP(nn.Module):
152
+ packed_modules_mapping = { # <-- ADD THIS BLOCK
153
+ "fused_wqa_wkv": ["wq_a", "wkv"],
154
+ "fused_wkv_wgate": ["wkv", "wgate"],
155
+ "gate_up_proj": ["w1", "w3"],
156
+ }
157
+
158
+ def __init__(self, *, vllm_config, prefix=""):
159
+ ...
160
+ ```
161
+
162
+ #### Patch 4c — `.weight_scale` (no `_inv`) in MTP loader
163
+
164
+ In `DeepSeekV4MTP.load_weights` find the suffix pick logic and change:
165
+
166
+ ```python
167
+ suffix = (
168
+ expert_scale_suffix
169
+ if _EXPERT_SCALE_RE.search(name)
170
+ else ".weight_scale" # <-- was ".weight_scale_inv"
171
+ )
172
+ ```
173
+
174
+ If anything goes sideways, sanity-check against the local diff after applying — `git diff vllm/model_executor/models/deepseek_v4_mtp.py` should show three hunks: (a) `prefix=f"{prefix}.e_proj"` and `prefix=f"{prefix}.h_proj"` added in the `DeepSeekV4MultiTokenPredictorLayer.__init__` constructor calls, (b) the `packed_modules_mapping` dict added as a class attribute on `DeepSeekV4MTP` immediately above its `__init__`, and (c) the `else ".weight_scale_inv"` line in `DeepSeekV4MTP.load_weights` changed to `else ".weight_scale"`.
175
+
176
+ ### Build vLLM
177
+
178
+ ```bash
179
+ cd $HOME/dsv4-local/src/vllm
180
+ export CUDA_HOME=$HOME/dsv4-local/conda-cuda
181
+ export PATH=/usr/bin:$CUDA_HOME/bin:$PATH
182
+ export LD_LIBRARY_PATH=$CUDA_HOME/lib:$LD_LIBRARY_PATH
183
+ export CPATH=$CUDA_HOME/include:$CPATH
184
+ export TORCH_CUDA_ARCH_LIST=12.0a
185
+ export CUDA_ARCH_LIST=120a
186
+ export CC=/usr/bin/gcc CXX=/usr/bin/g++ CUDAHOSTCXX=/usr/bin/g++
187
+ export NVCC_PREPEND_FLAGS="-ccbin /usr/bin/g++"
188
+ pip install -e . # ~20-30 min on a fast box
189
+ python -c "import vllm; print(vllm.__version__)"
190
+ python -c "from vllm.model_executor.models.deepseek_v4 import DeepseekV4ForCausalLM; print('OK')"
191
+ ```
192
+
193
+ If the build fails: the most common causes are (a) host gcc too new for nvcc 12.9, fixed by exporting CC/CXX above; (b) Triton can't find `pyconfig.h`, fix by `export CPATH=$CUDA_HOME/include:/usr/include/x86_64-linux-gnu/python3.12:$CPATH`. Stop and ask the human if those don't fix it — don't pivot to vanilla vLLM.
194
+
195
+ ---
196
+
197
+ ## Phase 5 — model download (143 GB)
198
+
199
+ ```bash
200
+ mkdir -p $HOME/dsv4-local/models
201
+ HF_HUB_ENABLE_HF_TRANSFER=1 hf download \
202
+ LordNeel/DeepSeek-V4-Flash-Acti-MTP-W4A16-FP8 \
203
+ --local-dir $HOME/dsv4-local/models/DeepSeek-V4-Flash-Acti-MTP-W4A16-FP8
204
+ ```
205
+
206
+ This is the v2 GPTQ release. Expect ~30-60 min on a 100 MB/s connection. The 4 base shards (~50 GB each) will hash-dedupe against pasta-paul's repo if you've already downloaded that.
207
+
208
+ Verification:
209
+
210
+ ```bash
211
+ ls $HOME/dsv4-local/models/DeepSeek-V4-Flash-Acti-MTP-W4A16-FP8/*.safetensors | wc -l # → 5
212
+ du -sh $HOME/dsv4-local/models/DeepSeek-V4-Flash-Acti-MTP-W4A16-FP8 # → ~146G
213
+ python -c "
214
+ from safetensors import safe_open
215
+ import json
216
+ idx = json.load(open('$HOME/dsv4-local/models/DeepSeek-V4-Flash-Acti-MTP-W4A16-FP8/model.safetensors.index.json'))
217
+ keys = list(idx['weight_map'])
218
+ print('total tensors:', len(keys))
219
+ print('mtp.0.* tensors:', sum(1 for k in keys if k.startswith('mtp.')))
220
+ print('mtp.0.ffn.experts.0.w1.weight_packed present:',
221
+ 'mtp.0.ffn.experts.0.w1.weight_packed' in keys)
222
+ "
223
+ ```
224
+
225
+ Expected: ~102k tensors, 2338 mtp.* tensors, w1.weight_packed True.
226
+
227
+ ---
228
+
229
+ ## Phase 6 — write serve script + env
230
+
231
+ ```bash
232
+ mkdir -p $HOME/dsv4-local/scripts
233
+ cat > $HOME/dsv4-local/scripts/serve_524k.sh <<'EOF'
234
+ #!/usr/bin/env bash
235
+ set -euo pipefail
236
+ ROOT=$HOME/dsv4-local
237
+ source "$ROOT/venvs/vllm-dsv4/bin/activate"
238
+
239
+ export CUDA_VISIBLE_DEVICES=0,1
240
+ export CUDA_HOME=$ROOT/conda-cuda
241
+ export PATH=/usr/bin:$CUDA_HOME/bin:$PATH
242
+ export TRITON_PTXAS_PATH=$CUDA_HOME/bin/ptxas
243
+ export LD_LIBRARY_PATH=$CUDA_HOME/lib:${LD_LIBRARY_PATH:-}
244
+ export CPATH=$CUDA_HOME/include:${CPATH:-}
245
+ export TORCH_CUDA_ARCH_LIST=12.0a
246
+ export CUDA_ARCH_LIST=120a
247
+
248
+ export VLLM_USE_FLASHINFER_SAMPLER=0
249
+ export VLLM_ENABLE_DEEPSEEK_V4_SPARSE_MLA_WARMUP=0
250
+ export VLLM_ENGINE_READY_TIMEOUT_S=3600
251
+ export PYTHONUNBUFFERED=1
252
+
253
+ # NCCL: validated for Max-Q PCIe topology
254
+ export NCCL_DEBUG=WARN
255
+ export NCCL_P2P_DISABLE=1
256
+ export NCCL_SHM_DISABLE=0
257
+ export NCCL_IB_DISABLE=1
258
+ # small-msg latency tuning (drops TTFT 154ms -> 91ms on Max-Q at zero decode cost)
259
+ export NCCL_PROTO=LL
260
+ export NCCL_ALGO=Ring
261
+ export NCCL_MIN_NCHANNELS=8
262
+ export NCCL_NTHREADS=512
263
+
264
+ MODEL=$ROOT/models/DeepSeek-V4-Flash-Acti-MTP-W4A16-FP8
265
+
266
+ exec vllm serve "$MODEL" \
267
+ --served-model-name deepseek-v4-flash deepseek-v4-flash-mtp DSV4-W4A16-FP8 deepseek-ai/DeepSeek-V4-Flash \
268
+ --tensor-parallel-size 2 \
269
+ --kv-cache-dtype fp8 \
270
+ --block-size 256 \
271
+ --max-model-len 524288 \
272
+ --max-num-seqs 2 --max-num-batched-tokens 8192 \
273
+ --gpu-memory-utilization 0.93 \
274
+ --tokenizer-mode deepseek_v4 \
275
+ --tool-call-parser deepseek_v4 --enable-auto-tool-choice \
276
+ --reasoning-parser deepseek_v4 \
277
+ --trust-remote-code \
278
+ --disable-custom-all-reduce \
279
+ --speculative-config '{"method":"mtp","num_speculative_tokens":1}' \
280
+ --host 0.0.0.0 --port 8000
281
+ EOF
282
+ chmod +x $HOME/dsv4-local/scripts/serve_524k.sh
283
+ ```
284
+
285
+ **Hardware-specific edits to make**:
286
+ - If running on RTX PRO 6000 **Server** (with NVLink): you can drop `--disable-custom-all-reduce` AND you can drop the `NCCL_P2P_DISABLE`/`NCCL_PROTO=LL` block. CustomAllreduce works on NVLink and is a bit faster.
287
+ - If running on H200: same as Server (NVLink available); also you'll likely run TP=4 or higher — adjust `--tensor-parallel-size` and `CUDA_VISIBLE_DEVICES` accordingly. **Do NOT use TP≥4 with W4A16 quants** — there's an upstream MoE scale-sharding bug ([vllm-project/vllm#41511](https://github.com/vllm-project/vllm/issues/41511)).
288
+ - If running on DGX Spark / GB10: same as Max-Q (no NVLink). Keep all flags.
289
+
290
+ ---
291
+
292
+ ## Phase 7 — start the server, wait for ready
293
+
294
+ ```bash
295
+ setsid bash $HOME/dsv4-local/scripts/serve_524k.sh > $HOME/dsv4-local/serve.log 2>&1 &
296
+ echo "started pid=$!"
297
+
298
+ # Wait for readiness (≤5 min cold)
299
+ until grep -q "Application startup complete" $HOME/dsv4-local/serve.log 2>/dev/null; do
300
+ if grep -qE "(Traceback|RuntimeError|Engine core init.*failed|Worker proc.*died)" $HOME/dsv4-local/serve.log; then
301
+ echo "FAILED — see $HOME/dsv4-local/serve.log"
302
+ tail -50 $HOME/dsv4-local/serve.log
303
+ exit 1
304
+ fi
305
+ sleep 2
306
+ done
307
+ curl -fsS http://127.0.0.1:8000/health -o /dev/null && echo "health OK"
308
+ ```
309
+
310
+ Expected timing on a 2× Max-Q: weight load ~30 s, KV cache + warmup ~30 s, graph capture ~5 s, total ~75 s wall.
311
+
312
+ ### Failure modes to recognize and remediate
313
+
314
+ | Symptom in log | Cause | Fix |
315
+ |---|---|---|
316
+ | `NotImplementedError: DeepSeekV4 requires FP8 attention quantization` | Loaded a non-FP8-attn variant (e.g. Intel/AutoRound) | Use the LordNeel repo, NOT a different DSV4 quant |
317
+ | `Unable to find matching target for ''` | Patch 4a (e_proj/h_proj prefix) missing | Apply Patch 4a |
318
+ | `KeyError: attn.fused_wqa_wkv.weight_scale_inv` (mtp_block) | Patch 4b (`packed_modules_mapping` on `DeepSeekV4MTP`) missing | Apply Patch 4b |
319
+ | `ValueError: Unable to find matching target for model.layers.43.e_proj` | Out-of-date config.json (ignore list missing layer 43 prefixes) | Re-pull the model — that bug is fixed in v2 |
320
+ | Hangs at `gpu_worker.py:619 CUDA graph pool memory` then loops `shm_broadcast.py:681` | CustomAllreduce deadlock on Max-Q | Add `--disable-custom-all-reduce` |
321
+ | `KeyError: experts.w13_weight` | Loaded the v1 RTN ckpt by mistake | Pull v2 (current main branch on Hub) |
322
+
323
+ ---
324
+
325
+ ## Phase 8 — smoke tests
326
+
327
+ ```bash
328
+ # Non-streaming chat
329
+ curl -sS -X POST http://127.0.0.1:8000/v1/chat/completions \
330
+ -H "Content-Type: application/json" -H "Authorization: Bearer EMPTY" \
331
+ --data '{
332
+ "model":"deepseek-v4-flash","stream":false,"max_tokens":64,"temperature":0.0,
333
+ "messages":[{"role":"user","content":"Say OK."}]
334
+ }' | python -c "import json,sys; d=json.load(sys.stdin); print(d['choices'][0]['message'].get('content') or '(empty content — check reasoning_content)')"
335
+
336
+ # Streaming
337
+ curl -sS -X POST http://127.0.0.1:8000/v1/chat/completions \
338
+ -H "Content-Type: application/json" -H "Authorization: Bearer EMPTY" \
339
+ --data '{
340
+ "model":"deepseek-v4-flash","stream":true,"max_tokens":32,"temperature":0.0,
341
+ "messages":[{"role":"user","content":"hi"}]
342
+ }' | head -20
343
+ ```
344
+
345
+ If `content` is empty even on simple prompts, that's the deepseek_v4 reasoning-parser putting output into `reasoning_content`. Read both fields:
346
+
347
+ ```python
348
+ msg = response["choices"][0]["message"]
349
+ text = msg.get("content") or msg.get("reasoning_content") or ""
350
+ ```
351
+
352
+ ---
353
+
354
+ ## Phase 9 — hand-off
355
+
356
+ Once Phase 8 passes, the agent should:
357
+
358
+ 1. Print the listen address: `http://<host>:8000/v1`
359
+ 2. Print the served model names: `deepseek-v4-flash`, `deepseek-v4-flash-mtp`, `DSV4-W4A16-FP8`, `deepseek-ai/DeepSeek-V4-Flash`
360
+ 3. Note that the API key is the literal string `EMPTY` (vLLM's default for unauthenticated)
361
+ 4. Print expected single-stream decode TPS for the configured profile (524k → ~85; 128k → ~111)
362
+ 5. Tell the human about reasoning_parser and `--reasoning-parser deepseek_v4` (their client may need to read both `content` and `reasoning_content`)
363
+
364
+ Do NOT proceed to fine-tuning, hot-swapping, or modifying the running server without explicit human approval.
365
+
366
+ ---
367
+
368
+ ## Phase 10 — optional: GPU clock unlock (sudo, +0-1% TPS)
369
+
370
+ If on Max-Q and the human wants the last 1%:
371
+
372
+ ```bash
373
+ # REQUIRES SUDO. Stop and ask the human first.
374
+ sudo nvidia-smi -pm 1
375
+ sudo nvidia-smi -pl 325 -i 0; sudo nvidia-smi -pl 325 -i 1
376
+ sudo nvidia-smi -lgc 2700 -i 0; sudo nvidia-smi -lgc 2700 -i 1
377
+ # revert: sudo nvidia-smi -rgc -i 0,1; sudo nvidia-smi -pl 300 -i 0,1
378
+ ```
379
+
380
+ Honest expectation: Max-Q firmware caps the achievable boost at ~2325 MHz under sustained 99% SM load regardless of the lock value. The +1% gain is real but small. Skip this unless the human asks for it.
381
+
382
+ ---
383
+
384
+ ## Quick reference: where things live in the reference layout
385
+
386
+ ```
387
+ $HOME/dsv4-local/
388
+ ├── conda-cuda/ # CUDA 12.9 toolkit (no system change)
389
+ ├── miniforge3/ # conda installer
390
+ ├── venvs/vllm-dsv4/ # the only Python venv you need
391
+ ├── src/vllm/ # patched jasl/vllm fork
392
+ ├── models/DeepSeek-V4-Flash-Acti-MTP-W4A16-FP8/
393
+ └── scripts/serve_524k.sh
394
+ ```
395
+
396
+ ## Questions an agent should ask the human (only when triggered)
397
+
398
+ | Trigger | Ask |
399
+ |---|---|
400
+ | < 2× 96 GB GPUs found | "Hardware doesn't fit a 524k TP=2 profile. Want to try smaller profiles or stop?" |
401
+ | Build fails with cuda/nvcc errors after the documented fixes | "Build broken. Want me to pivot to vanilla vLLM (won't load this model) or stop?" |
402
+ | Phase 7 hangs > 5 min with no log progress | "Server isn't responding; want me to dump py-spy stacks (needs sudo) or kill and retry with `--enforce-eager`?" |
403
+ | Phase 10 (sudo clock unlock) | always ask before running |
404
+ | User asks about TP > 2 | "Upstream W4A16 MoE scale-sharding bug — issue #41511. TP=4 will OOM/error. Want to stop or proceed anyway?" |