Optimize Model — Inference Services
Analyze a model server's code and deployment config for performance optimization opportunities. Covers the full stack: model code → inference backend tuning → GPU/CPU settings → KServe config → K8s resources.
Steps
- Read
src/models/<model-name>/model_server/model.py(orsrc/models/<model-name>/model.py) to understand the model class, env vars, and runtime configuration. - Read
src/models/<model-name>/README.mdfor the model card, which documents the model architecture, training framework, hardware requirements, and expected input/output schema. Use this to confirm whether the model is CPU or GPU, which inference backend it uses, and any documented performance expectations. - Read
src/models/<model-name>/requirements.txtandpython/requirements.txtto check dependency constraints. - Fetch the deployment chart from
operations/deployment-chartsathelmfile.d/ml-services/<chart-name>/values.yamland environment overrides (values-ml-serve-eqiad.yamlfor prod). - Fetch upstream best practices to use as a baseline for the analysis:
- If the model uses vLLM: identify the model family from the HuggingFace model ID in
model.pyor the README model card (e.g., GPT-Oss →gpt-oss, Qwen →qwen, Llama →llama) and fetchhttps://recipes.vllm.ai/{family}/{model-name}for the recommended vLLM configuration. - If the model runs on AMD GPUs (MI300X, MI250, MI210): fetch the ROCm vLLM optimization guide at
https://rocm.docs.amd.com/en/latest/how-to/rocm-for-ai/inference-optimization/vllm-optimization.htmland the AITER README athttps://github.com/ROCm/aiterfor known issues and tuning recommendations. - If the model uses HF Transformers (no vLLM): fetch the HuggingFace model card for the model to check for recommended inference settings.
- Cross-reference upstream recommendations against the current configuration found in the model code and deployment chart.
- If the model uses vLLM: identify the model family from the HuggingFace model ID in
- Determine the optimization scope based on the model's hardware target:
- If the model is CPU-only (no GPU resources in chart, no CUDA/ROCm imports in code): ask the user whether they want to optimize for CPU only, or also assess GPU migration potential. If CPU-only, skip the vLLM and ROCm sections below and focus on KServe workers, external API optimization, K8s CPU/memory/HPA, and Python patterns.
- If the model is GPU (has
amd.com/gpuornvidia.com/gpuin chart, imports vLLM/ROCm in code): run all sections below.
- Analyze across the following dimensions (scope per step 6):
Inference Backend
- Which inference backend is used (HF Transformers, vLLM, custom)? If using HF Transformers, flag vLLM+AITER migration as a potential improvement for throughput and memory efficiency via PagedAttention.
- For vLLM models: is
AsyncLLMEngineused for non-blocking generation? Falls back to synchronous generation? - Model quantization: int4, int8, float16? Matches the hardware capability (MI300X for GPU, AVX/AMX for CPU)?
- CPU models: is ONNX Runtime, OpenVINO, or TorchServe used? These can offer better CPU throughput than vanilla HF Transformers.
vLLM Configuration (GPU only)
tensor_parallel_size— matches GPU count in K8s resources? For MI300X, TP=2 is typical for 20B+ models; check if it can be increased.gpu_memory_utilization— default 0.95 is aggressive; check for OOM risk vs underutilization.max_num_seqs/max_num_batched_tokens— balanced for the model's expected concurrency?block_size— 64 is common for AMD; 128 can be more efficient for long sequences.max_model_len— matches actual usage patterns? Overprovisioning wastes GPU memory.enable_prefix_caching— enabled in code? Reduces latency for repeated prompts.attention_backend—ROCM_AITER_UNIFIED_ATTNrequiresVLLM_ROCM_USE_AITER=1. Check consistency.compilation_config—use_inductor_graph_partitionenabled? Missing tuning?disable_custom_all_reduce— should beTruefor >1 GPU on MI300X in some topologies.- Inter-GPU communication topology: P2P vs SHM vs P2P+SHM? Check if
NCCL_P2P_LEVEL,/dev/shmsizing, andHSA_FORCE_FINE_GRAIN_PCIEare correctly configured for the chosen topology.
ROCm / GPU Tuning (GPU only)
VLLM_ROCM_USE_AITER— set to1for flash attention on MI300X?TORCH_BLAS_PREFER_HIPBLASLT— set to1for optimized GEMM kernels on MI300X.HSA_FORCE_FINE_GRAIN_PCIE— set to1when using P2P for fine-grained PCIe access.HSA_ENABLE_IPC_MODE_LEGACY—0for P2P mode,1for IPC/SHM fallback.- NCCL/RCCL vars:
NCCL_P2P_DISABLE,NCCL_SOCKET_IFNAME,RCCL_MSCCL_ENABLE. - Shared memory (
/dev/shm) — configured asemptyDirwith adequatesizeLimitwhen TP>1? TORCH_SYMM_MEM_DISABLE_MULTICAST— set for P2P stability?- Build-time vs runtime compilation: are ROCm device bitcode libraries included in the Docker image to avoid lazy runtime compilation on first inference?
External Dependencies
- Does preprocessing make external API calls (MediaWiki, Wikidata, etc.)? Are they async or blocking?
- Caching: are external API responses cached to avoid redundant calls on repeated inputs? Check for TTL, max size, and eviction policy.
- Retry logic: is there exponential backoff or retry for transient failures in external calls? Does the code distinguish transient vs permanent errors?
- Connection pooling: are HTTP sessions reused or created per-request? Check for
mwapi.AsyncSessionoraiohttp.ClientSessionreuse patterns. - Timeouts: are timeouts configured for external calls? Missing timeouts can cause requests to hang indefinitely.
- Error taxonomy: are errors categorized (network timeout, API overload, bad entity ID, type error) and handled differently per category?
KServe / Model Server Config
workers=inModelServer(workers=N)— for CPU I/O-bound models, increasing workers can significantly improve throughput (e.g., 8 workers per pod for Wikidata-heavy models). For GPU models, more workers risk OOM; test incrementally.- Model loading: does
load()download or read local path? Cold start time matters. - Preprocessing: async or sync? Blocking calls stall the event loop.
- Batching: is vLLM continuous batching configured? Check
max_num_seqs. For CPU models, does KServe's built-in batching help? - Timeouts: any request timeout settings that might cut off long inferences?
Python / Code Patterns
- Model class structure: clean separation of
load,preprocess,predict,postprocess? - Caching: repeated computation in preprocessing (e.g., fetching article HTML every request)?
- Error handling: graceful degradation vs hard failures? Are there fallback paths for external API failures?
- Logging: excessive logging in hot path? KServe log level configuration?
- CPU models: is there GIL contention from threading? Would
NUM_OF_WORKERSwith multiple processes help? - Memory management: are large objects (models, caches) properly scoped? Any risk of memory leaks under sustained load?
Kubernetes Resources
- CPU/memory ratio: GPU models typically need 8-16 CPU and 16-80Gi memory per GPU. CPU models need CPU/memory proportional to worker count and external API concurrency.
- GPU count: matches
tensor_parallel_sizein vLLM config? (GPU only) - Node affinity: GPU models pinned to MI300X nodes? Check
dedicated=mi300x-experimentstoleration. CPU models: any node constraints? - Scaling:
maxReplicas— GPU models often pinned to 1; is HPA configured? For CPU models, is autoscaling configured based on RPS or CPU utilization? Check stabilization window, scale-down behavior, and pod disruption budget. - Shared memory volume: present and correctly sized for TP>1? (GPU only)
- Resource quota: does the namespace have sufficient headroom for the configured replicas × resources per pod?
- Produce a structured report with:
- Findings organized by layer (Inference Backend, vLLM/ROCm [if GPU], External Dependencies, KServe, Python, K8s)
- Severity for each finding: critical / major / suggestion
- Rationale explaining why it matters for your stack
- Recommended change with concrete code or config diff
Notes
- Model code is in
src/models/<name>/(directories use snake_case, e.g.,revert_risk_model). - Deployment charts are in
operations/deployment-chartsunderhelmfile.d/ml-services/<name>/. - Chart names sometimes differ from model directory names.
- For GPU models: confirm the chart uses
amd.com/gpu(notnvidia.com/gpu). - For CPU models: check the README for the model card — WMF-trained models document architecture, training data, and expected performance.
- Model artifacts are stored in S3 at
s3://wmf-ml-models/<model-name>/. - vLLM settings can often be tuned without code changes via env vars in the chart.
Input
$ARGUMENTS — the model name as it appears in src/models/ (e.g., policy_violation, articlequality, revert_risk_model).