| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- #!/usr/bin/env python3
- """Cap each worker's share of the GB10's memory.
- vLLM never calls set_per_process_memory_fraction, so nothing bounds a worker:
- gpu_memory_utilization only sizes the KV pool, and every allocation outside it
- (the sparse indexer scores chunk x context/kpool, and grows with the session)
- takes host memory until the node stops forking and the watchdog resets it. On
- unified memory there is no separate VRAM to run out of first, and the OOM
- killer cannot reclaim a CUDA allocation.
- A fraction here turns that into torch.OutOfMemoryError: one request fails and
- the node keeps serving. Leave TORCH_MEM_FRACTION above gpu_memory_utilization,
- far enough that weights, KV and a full prefill's scratch all fit under it, and
- below 1.0 by whatever the host needs to stay alive.
- spark_mem_trace carries the logic and reads its own env at device init, so
- both the ceiling and the trace tune from .env without re-patching.
- """
- from pathlib import Path
- WORKER = Path(
- "/usr/local/lib/python3.12/dist-packages/vllm/v1/worker/gpu_worker.py"
- )
- ANCHOR = " torch.accelerator.set_device_index(self.device)\n"
- MARKER = "# [spark-mem-cap]"
- INSERT = f""" {MARKER}
- import spark_mem_trace
- spark_mem_trace.arm(self.device)
- """
- def main() -> None:
- text = WORKER.read_text()
- if MARKER in text:
- print("glm53: worker memory cap already patched")
- return
- if text.count(ANCHOR) != 1:
- raise SystemExit(
- f"glm53: expected exactly one device-init anchor in {WORKER.name}, "
- f"found {text.count(ANCHOR)} -- re-check the worker after a base bump"
- )
- WORKER.write_text(text.replace(ANCHOR, ANCHOR + INSERT, 1))
- cache = WORKER.parent / "__pycache__"
- if cache.is_dir():
- for pyc in cache.glob("gpu_worker*.pyc"):
- pyc.unlink(missing_ok=True)
- print("glm53: patched worker memory cap (TORCH_MEM_FRACTION arms it)")
- if __name__ == "__main__":
- main()
|