Skip to content
Back to skills

Multi Gpu Process Isolated Vllm

ASecurity

Run independent vLLM workers on each GPU by spawning one mp.Process per device and setting CUDA_VISIBLE_DEVICES inside the child before vLLM is imported, sidestepping vLLM's single-instance-per-process limitation

  • 61 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 12, 2026
ai-agentspythongonode

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill multi-gpu-process-isolated-vllm --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Multi Gpu Process Isolated Vllm?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Multi Gpu Process Isolated Vllm
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-multi-gpu-process-isolated-vllm/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-multi-gpu-process-isolated-vllm)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: llm-multi-gpu-process-isolated-vllm
description: Run independent vLLM workers on each GPU by spawning one mp.Process per device and setting CUDA_VISIBLE_DEVICES inside the child before vLLM is imported, sidestepping vLLM's single-instance-per-process limitation
---

## Overview

vLLM holds CUDA context globally inside its process — you cannot create two `LLM(...)` objects in the same Python process and pin them to different GPUs. On Kaggle's 2xT4 / 2xL4 nodes that means half your hardware sits idle unless you go tensor-parallel (which forces both GPUs to host the *same* model, halving max batch). The workaround: `multiprocessing.spawn` one child process per GPU, set `os.environ['CUDA_VISIBLE_DEVICES']` *inside* the child before any `import vllm`, then have each child run `tensor_parallel_size=1` on its own GPU. Gather results through a `Manager().dict()`. This lets you run two *different* models (e.g. Qwen-7B on GPU 0, Llama-8B on GPU 1) or shard a long input list across two copies of the same model.

## Quick Start

```python
import multiprocessing as mp
import os

def worker(gpu_id, prompts, return_dict, model_path):
    os.environ['CUDA_VISIBLE_DEVICES'] = str(gpu_id)
    from vllm import LLM, SamplingParams              # import AFTER env var
    llm = LLM(model=model_path, tensor_parallel_size=1,
              gpu_memory_utilization=0.92, max_model_len=4096)
    out = llm.generate(prompts, SamplingParams(temperature=0, max_tokens=4))
    return_dict[gpu_id] = [o.outputs[0].text for o in out]

if __name__ == '__main__':
    mp.set_start_method('spawn', force=True)
    manager = mp.Manager()
    results = manager.dict()
    n = len(all_prompts)
    procs = [
        mp.Process(target=worker, args=(0, all_prompts[:n//2], results, MODEL)),
        mp.Process(target=worker, args=(1, all_prompts[n//2:], results, MODEL)),
    ]
    for p in procs: p.start()
    for p in procs: p.join()
    merged = results[0] + results[1]
```

## Workflow

1. `mp.set_start_method('spawn', force=True)` — fork inherits CUDA context and crashes
2. Define a `worker(gpu_id, ...)` function that sets `CUDA_VISIBLE_DEVICES` *as the first line*, then imports vLLM
3. Split the prompt list across N GPUs; each child sees only its slice
4. Use a `Manager().dict()` keyed by `gpu_id` to collect outputs (regular dicts don't survive process boundaries)
5. `start()` all, then `join()` all — never `start();join()` sequentially or you serialize them
6. Concatenate results in a deterministic order after all processes return

## Key Decisions

- **Set `CUDA_VISIBLE_DEVICES` before `import vllm`, not before `LLM(...)`**: vLLM grabs CUDA at import time on some versions; setting the env later is too late.
- **`spawn`, not `fork`**: fork copies the parent's CUDA state, which is corrupted and segfaults on first GPU op.
- **`tensor_parallel_size=1` per child**: each child sees only one GPU thanks to the env var; setting tp=2 inside a child fails because the other GPU is masked.
- **vs. true tensor parallel**: tp shards one model across both GPUs (lower latency, same throughput); process isolation runs two model copies (higher throughput, can host different models). For batch inference, isolation is almost always faster.
- **`gpu_memory_utilization=0.92`, not 0.95**: leaves headroom for the manager + Python overhead per process.

## References

- [Test on testdataset (Qwen embedding + Llama + LR)](https://www.kaggle.com/competitions/jigsaw-agile-community-rules)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…