Deployment record: serving GLM-5.2 (704 GB, FP8) with SGLang inside an Apptainer container on a Slurm HPC cluster. Hardware: single node, 8× NVIDIA H200 141 GB (TP8), driver 580.65.06, CUDA 13.0. Result: 3.41 ms median TPOT / 164 tok/s single-stream with EAGLE MTP (accept length 4.21); 9/9 API smoke tests pass.
Hardware:
- 1 node × 8 NVIDIA H200 (141 GB HBM3e each)
- Intel Xeon Platinum 8480+ (112 CPU cores)
- ~2 TB RAM
- NVLink: 18 links/GPU at 26.562 GB/s
- Driver: 580.65.06, CUDA 13.0
Software:
- Apptainer/Singularity (for container)
- SGLang v0.5.14 (from
lmsysorg/sglang:latest) - PyTorch 2.11.0+cu130
Account: <project-account>
All large data lives under $WORK/glm-5.2-sglang/:
$WORK/glm-5.2-sglang/
├── models/GLM-5.2-FP8/ ← 704 GB FP8 model weights
├── containers/sglang-glm52.sif ← SGLang Apptainer image (11 GB)
├── hf-cache/ ← Hugging Face cache
├── logs/ ← Server & job logs
├── results/ ← Benchmark results
├── torch-cache/ ← Torch extensions
├── triton-cache/ ← Triton cache
├── flashinfer-cache/ ← FlashInfer workspace
└── tmp/ ← Temporary files
# Direct download (no sbatch needed)
source config/runtime.env
export HF_HOME HF_HUB_CACHE
mkdir -p "$MODEL_DIR" "$HF_HUB_CACHE"
pip install huggingface_hub
python3 scripts/download_model.pyOr via sbatch:
sbatch --account=$SLURM_ACCOUNT slurm/download_model.sbatchPulled from docker://lmsysorg/sglang:latest:
source config/runtime.env
export APPTAINER_TMPDIR="$TMPDIR"
export APPTAINER_CACHEDIR="$WORK_ROOT/apptainer-cache"
apptainer pull "$CONTAINER_DIR/sglang-glm52.sif" docker://lmsysorg/sglang:latestSGLang version: 0.5.14
Quick single-GPU check:
sbatch --account=$SLURM_ACCOUNT slurm/gpu_diagnostic.sbatchPre-compile Triton kernels before serving to avoid 10-20 min JIT warmup:
sbatch --account=$SLURM_ACCOUNT slurm/compile_deep_gemm.sbatchUses 8×H200 with the same container and model path. Triton cache saved to $TRITON_CACHE_DIR (~17 MB). Does not delete existing caches.
Submit 8×H200 low-latency job (1 hour):
sbatch --account=$SLURM_ACCOUNT slurm/serve_low_latency.sbatchLaunch command:
sglang serve \
--model-path $WORK/glm-5.2-sglang/models/GLM-5.2-FP8 \
--served-model-name glm-5.2 \
--tp-size 8 \
--reasoning-parser glm45 \
--tool-call-parser glm47 \
--speculative-algorithm EAGLE \
--speculative-num-steps 5 \
--speculative-eagle-topk 1 \
--speculative-num-draft-tokens 6 \
--max-running-requests 8 \
--mem-fraction-static 0.8 \
--host 0.0.0.0 \
--port 30000# Check health
curl http://<node>:30000/health
# OpenAI-compatible API
curl http://<node>:30000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.2",
"messages": [{"role": "user", "content": "Hello"}],
"max_tokens": 100
}'ssh -L 30000:node<NNN>:30000 <cluster-login-host>
# Then access via http://127.0.0.1:30000sacct -j <JOBID> --format=JobID,JobName,Partition,State,ExitCode,Elapsed,MaxRSS,MaxVMSize
seff <JOBID>| Path | Contents |
|---|---|
$WORK_ROOT/logs/ |
Job stdout/stderr, server logs |
$WORK_ROOT/results/<timestamp>-low-latency/ |
Benchmarks, smoke test, GPU metrics |
$WORK_ROOT/results/<timestamp>-low-latency/gpu_metrics/ |
GPU dmon data |
reports/ |
Summary reports (environment, deployment status, benchmarks) |
9/9 tests passed.
| Test | Status |
|---|---|
| Visible content without thinking | ✅ "Hello, how are you today?" |
| Tool calling (glm47 parser) | ✅ get_weather({"city": "Taipei"}) |
| Reasoning parser (glm45) | ✅ reasoning + visible content separated |
| Total | 9 PASS, 0 FAIL |
Server started in 200s. All 9 smoke tests passed on first attempt with the updated script.
Benchmark A: Single user (10 prompts, 1 concurrent)
| Metric | Round 1 | Round 2 |
|---|---|---|
| Output throughput | 66.81 tok/s | 164.35 tok/s |
| Mean TTFT | 1498 ms | 258 ms |
| Median TPOT | 3.42 ms | 3.41 ms |
| Accept length | 4.14 | 4.21 |
| Successful | 10/10 | 10/10 |
Benchmark B: Concurrency 4 (32 prompts)
| Metric | Round 1 | Round 2 |
|---|---|---|
| Output throughput | 252.28 tok/s | 322.00 tok/s |
| Mean TTFT | 568 ms | 344 ms |
| Median TPOT | 10.30 ms | 8.77 ms |
| Accept length | 4.16 | 4.17 |
| Successful | 32/32 | 32/32 |
Round 2 improvement from DeepGEMM pre-compilation and fixed smoke test.
- Tokenizer warning in bench_serving:
Fail to load tokenizer config with error=glm-5.2 is not a local folder. Benign — does not affect correctness.--tokenizer "$MODEL"is already passed. - No HF_TOKEN set: Unauthenticated downloads are rate-limited. Set
HF_TOKENfor faster HuggingFace access. - Peak HBM usage ~97%: With
--mem-fraction-static 0.8, H200 HBM reaches ~143 GB / 141 GB. Monitor OOM risks under higher concurrency.
- ✅
Run— Done (job 162060)sglang.compile_deep_gemm** to pre-compile kernels - ✅
Fix smoke test for visible content with thinking— Done (job 162087, 9/9 PASS) - Balanced deployment: Tune
--mem-fraction-static, increase--max-running-requests. - High-throughput deployment: Increase concurrency with higher batch sizes.
- Production: Submit to
8gpuspartition for longer wall time (2 days).