Introduction
After running Qwen 3.6 35B A3B on K3s in production for several weeks, we’ve gathered a set of hard-won lessons. This post shares our operational experience, performance benchmarks, and the tweaks that made the difference between a clunky demo and a reliable service.
Model Selection Rationale
We chose Qwen 3.6 35B A3B because it offers an excellent balance of capability and resource efficiency:
- 35B parameters: Enough capability for complex reasoning tasks
- A3B (3-bit activation): Reduced memory footprint compared to full-precision models
- Open weights: No vendor lock-in, easy to update and iterate
- Mistral-compatible: Works with existing tooling and evaluation pipelines
Hardware Requirements
Minimum Viable Setup
| Component | Minimum | Recommended |
|---|---|---|
| GPU VRAM | 16 GB | 24 GB |
| RAM | 8 GB | 16 GB |
| Storage | 50 GB | 100 GB |
| CPU | 4 cores | 8 cores |
Our single-node setup uses a machine with an NVIDIA L4 GPU (24 GB VRAM) and 32 GB RAM. This handles the model comfortably with room for concurrent requests.
Memory Optimization Techniques
1. Quantization Strategy
We experimented with several quantization approaches:
# Example quantization configuration for vLLM
quantization_config = {
"quantization": "bitsandbytes",
"load_in_4bit": True,
"bnb_4bit_quant_type": "nf4",
"bnb_4bit_compute_dtype": "float16",
}
4-bit quantization reduced VRAM usage from ~70 GB (FP16) to ~20 GB — fitting comfortably within the L4’s 24 GB limit.
2. vLLM PagedAttention
Using vLLM’s PagedAttention mechanism improved memory utilization:
- Without PagedAttention: ~15 concurrent requests before OOM
- With PagedAttention: ~30+ concurrent requests
3. K3s Resource Limits
Properly configuring Kubernetes resource limits was critical:
resources:
requests:
nvidia.com/gpu: "1"
memory: "8Gi"
cpu: "2"
limits:
nvidia.com/gpu: "1"
memory: "12Gi"
cpu: "4"
The GPU limit is the most important — without it, the scheduler can’t place the pod on a GPU node.
Performance Benchmarks
Inference Latency
| Batch Size | Avg Latency (ms) | P99 Latency (ms) | Tokens/sec |
|---|---|---|---|
| 1 | 120 | 180 | ~45 |
| 4 | 95 | 250 | ~180 |
| 8 | 85 | 400 | ~320 |
| 16 | 90 | 800 | ~600 |
Key insight: batching dramatically improves throughput but increases P99 latency. For interactive use cases (chat), keep batch size at 1-4.
GPU Utilization
Monitoring with nvidia-smi dmon showed:
- Average GPU compute: 85-92% during active serving
- VRAM usage: ~18-20 GB (well under the 24 GB limit)
- GPU memory fragmentation: minimal with PagedAttention
Common Pitfalls and Fixes
Pitfall 1: GPU Not Detected
Symptom: Pods stuck in Pending state with Insufficient nvidia.com/gpu.
Fix: Verify the GPU operator is running:
kubectl get pods -n gpu-operator
kubectl logs -n gpu-operator -l app.kubernetes.io/component=gpu-feature-discovery
Pitfall 2: OOMKilled on CPU
Symptom: Pod crashes with OOMKilled despite low GPU usage.
Fix: The model loading phase spikes CPU memory. Increase CPU requests:
resources:
requests:
memory: "8Gi" # Increased from 4Gi
cpu: "2" # Increased from 1
Pitfall 3: Model Loading Timeout
Symptom: Readiness probe fails because the model takes longer to load than the timeout allows.
Fix: Use liveness probes instead of readiness for initial startup:
livenessProbe:
httpGet:
path: /health
port: 4000
initialDelaySeconds: 120
periodSeconds: 30
K3s-Specific Tips
Local PV for Model Cache
Store model weights on a local persistent volume to avoid repeated downloads:
apiVersion: v1
kind: PersistentVolume
metadata:
name: model-cache
spec:
capacity:
storage: 80Gi
accessModes:
- ReadWriteOnce
storageClassName: local-storage
local:
path: /data/models
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- gamorcloud01
NetworkPolicy for Model Gateway
Protect your LiteLLM gateway with a NetworkPolicy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: litellm-policy
namespace: ia-services-payed
spec:
podSelector:
matchLabels:
app: litellm
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: traefik
ports:
- port: 4000
Monitoring Setup
We use a simple but effective monitoring stack:
- nvidia-dcgm: GPU metrics (temperature, memory, utilization)
- Prometheus: Scrapes DCGM and K3s metrics
- Grafana: Dashboards for GPU health and model performance
The critical Grafana panels to watch:
GPU Memory Utilization— stay under 85%GPU Temperature— alert at 85°CRequest Latency— track P50 and P99GPU Utilization— should be above 70% during active serving
Conclusion
Running Qwen 3.6 35B A3B on K3s is entirely feasible on modest hardware, but it requires careful attention to GPU memory, resource limits, and monitoring. The biggest lesson: start with the hardware constraints and work backward, not the other way around. Quantization, proper resource limits, and monitoring are your best friends.