On-Prem LLM Inference A technical guide details the production deployment of on-premises large language model inference using vLLM, covering an 8-GPU node running GLM-5.2/5.3 (NVFP4 MoE) and a single L40S running gemma-4-26B FP8, with specific version requirements and patches. The article includes installation commands, model downloads, and workarounds for FlashInfer and CUDA graph memory issues, emphasizing stable configurations for 256K context and MTP speculative decoding. vLLM serving, production shape Context: on-prem LLM inference — the kind where the data cannot leave. Two serving profiles: an 8-GPU node running GLM-5.2/5.3 NVFP4 MoE, expert parallel, 256K context , and a single L40S running gemma-4-26B FP8. Ubuntu 24.04, vLLM in a uv-managed venv, systemd on top. The front door in front of these engines — keys, routing, TLS — is the LiteLLM proxy entry ../litellm-proxy/ . Hostnames genericized; the API key below is a placeholder. Install curl -LsSf https://astral.sh/uv/install.sh | sh source $HOME/.local/bin/env uv venv --python 3.12 --seed source .venv/bin/activate uv pip install vllm --torch-backend=auto The unglamorous apt layer underneath: ffmpeg torchcodec wants it , numactl NUMA binding , build-essential + python3.12-dev Triton compiles , ninja-build . Models pip install -U huggingface hub hf download nvidia/GLM-5.2-NVFP4 --local-dir /models/GLM-5.2-NVFP4 hf download google/gemma-4-26B-A4B-it --local-dir /models/gemma-4-26B-A4B-it hf download google/gemma-4-26B-A4B-it-assistant ... MTP draft model hf download Qwen/Qwen2.5-VL-72B-Instruct-AWQ ... vision What bit - — the pinned FlashInfer is older than the vLLM calling it. Upgrade FlashInfer and tell vLLM to stop checking versions: trtllm batch decode with kv cache mla got an unexpected keyword argument 'kv scale format' pip install -U flashinfer-python flashinfer-cubin export FLASHINFER DISABLE VERSION CHECK=1 - — a literally half-finished backend class for the SM120 GPU. Patch it: back up the file, apply the patch script, restart vLLM. Half finished FlashInferMLASparseSM120Impl - The CUDA graph memory hint nobody reads. At --gpu-memory-utilization 0.95 , vLLM logs that with CUDA graph memory profiling this is effectively 0.9124 — and suggests 0.9876 for the same usable KV cache. Tempting; 0.98 OOMs at 256K context on this hardware. 0.95 with --max-model-len 256K is the stable point. - Model upgrades pull vLLM upgrades. GLM-5.3-NVFP4 needed vLLM 0.28.0; the node ran 0.25.0. Back up the whole venv first cp -a .venv .venv-vllm025-backup , then: pip install -U "vllm =0.28.0" --extra-index-url https://flashinfer.ai/whl pip install -U flashinfer-cubin==0.6.16.post3 --extra-index-url https://flashinfer.ai/whl - MTP on gemma needed a patch to vllm/v1/spec decode/llm base proposer.py — the draft model's embedding path. Patch script writes its own .bak ; restart vLLM after. The serving commands 8-GPU node, the final stable shape: vllm serve /models/GLM-5.2-NVFP4 --served-model-name glm-5.2 \ --tensor-parallel-size 8 --enable-expert-parallel \ --disable-custom-all-reduce --numa-bind --performance-mode interactivity \ --trust-remote-code --kv-cache-dtype fp8 e4m3 \ --gpu-memory-utilization 0.95 --max-model-len 256K \ --host