TurboQuant Serde End-to-End Example
This example demonstrates the per-adapter serde feature: the L2 disk adapter quantizes KV cache to TurboQuant before writing to disk, and dequantizes back to the original dtype on prefetch.
What it does
- Starts an
lmcache serverwith:- L1: 20 GB CPU memory cache, LRU eviction
- L2: filesystem (disk) adapter at
/tmp/lmcache_turboquant_serde_disk - Serde:
TurboQuant(TurboQuant preset) attached to the L2 adapter
- Starts vLLM connected via
LMCacheMPConnector - Sends an inference request — KV is computed, written to L1, then asynchronously serialized (TurboQuant) and stored to L2 disk
- Calls the lmcache HTTP API to force-clear L1 (CPU cache)
- Re-sends the same request — L1 misses, L2 prefetch fires, the serialized bytes are loaded from disk and deserialized back into KV-shaped buffers, then vLLM resumes from cache
Files
run_serde_turboquant_example.sh— full end-to-end:lmcache server+vllm serve+ real inference, then clear L1 and re-infer to hit the L2 path.
Quick sanity check (no vLLM required)
The pytest suite includes TurboQuant serde tests that exercise direct CUDA, MockL2, and filesystem-backed L2 round-trips without needing vLLM:
CUDA_VISIBLE_DEVICES=0 python -m pytest tests/v1/distributed/serde/test_turboquant.py -q -s
Requirements
- vLLM installed (
vllm serveworks) lmcacheCLI installed (lmcache server --helpworks)- 1 GPU (default
CUDA_VISIBLE_DEVICES=0) - PyTorch + Triton CUDA environment
Run
./run_serde_turboquant_example.sh
You can override defaults via environment variables:
MODEL="meta-llama/Llama-3.1-8B-Instruct" \
GPU_DEVICE=0 \
L1_SIZE_GB=20 \
LMCACHE_PORT=6555 \
VLLM_PORT=8000 \
TQ_PRESET=turboquant_k8v4 \
TQ_BLOCK_SIZE=16 \
./run_serde_turboquant_example.sh
Server output is streamed to stdout. Logs are also saved under
/tmp/lmcache_turboquant_serde_example/{lmcache,vllm}.log (override with TMP_DIR).
L2 adapter config syntax
The serde is attached per-adapter via a serde sub-dict in the --l2-adapter
JSON. Each adapter independently decides whether to use serde.
{
"type": "fs",
"base_path": "/tmp/lmcache_turboquant_serde_disk",
"serde": {
"type": "turboquant",
"preset": "turboquant_k8v4",
"block_size": 16
}
}
To disable serde for an adapter, omit the serde field.
Adding a custom serde
-
Implement
SerializerandDeserializerfromlmcache.v1.distributed.serde -
Register a factory:
from lmcache.v1.distributed.serde import ( AsyncSerdeProcessor, register_serde_factory, ) def _create_my_serde(config: dict): return AsyncSerdeProcessor(MySerializer(), MyDeserializer()) register_serde_factory("mine", _create_my_serde) -
Reference it in the adapter config:
"serde": {"type": "mine", ...}