[FS-Offloading] Batch Lookup in C - #46713
Conversation
orozery
left a comment
There was a problem hiding this comment.
Thanks @varun-sundar-rabindranath !
Looks mostly good to me.
Can we add some tests? Claude suggestion:
- Unit test importing fsio_C.batch_lookup directly
- Edge cases: empty list, single element, mix of existing/non-existing paths
- Error case: list containing non-string (should raise TypeError)
- Test the fallback path when C extension is unavailable
| @@ -21,10 +21,17 @@ | |||
| from collections.abc import Iterable | |||
| from typing import TYPE_CHECKING | |||
|
|
|||
| try: | |||
| from vllm.fsio_C import batch_lookup as batch_lookup_C | |||
There was a problem hiding this comment.
can we rename fsio -> fs_io (throughout)?
There was a problem hiding this comment.
Made the change. The extensions are now fs_io_C 👍 this is a better name.
|
Hi @orozery Thanks for the review. I have addressed all the comments. Can you take another pass please. Thanks 🙌 |
|
@claude review |
|
|
||
| std::vector<int> exists_flags(n); | ||
| { | ||
| Py_BEGIN_ALLOW_THREADS _batch_lookup(paths, exists_flags); |
There was a problem hiding this comment.
nit:
| Py_BEGIN_ALLOW_THREADS _batch_lookup(paths, exists_flags); | |
| Py_BEGIN_ALLOW_THREADS | |
| _batch_lookup(paths, exists_flags); |
There was a problem hiding this comment.
I have been struggling with clang-format for this. Looks like spinloop.cpp is also suffering from the same
Line 149 in 96eb8dd
| # | ||
| # fsio extension (pure CXX; must stay above the non-CUDA device branch | ||
| # so CPU builds define the target before the early return). | ||
| # Provides batch faccessat(2) with a single GIL release for the entire batch, |
There was a problem hiding this comment.
| # Provides batch faccessat(2) with a single GIL release for the entire batch, | |
| # Provides batch access(2) with a single GIL release for the entire batch, |
There was a problem hiding this comment.
Removed references to batch_lookup and fixed the comment to be more generic as this module could be extended in the future.
687eb7f to
0766309
Compare
|
The two failing tests, nightly failure : |
Signed-off-by: Varun Sundar Rabindranath <varun-sundar-rabindranath@h100-01.nemg-001.lab.rdu2.dc.redhat.com> Signed-off-by: <>
Signed-off-by: Varun Sundar Rabindranath <varun-sundar-rabindranath@h100-01.nemg-001.lab.rdu2.dc.redhat.com> Signed-off-by: <>
0766309 to
6d18de5
Compare
|
Rebased to re-run the tests with latest main. |
|
Requesting force merge on this PR,
|
Signed-off-by: <> Co-authored-by: Varun Sundar Rabindranath <varun-sundar-rabindranath@h100-01.nemg-001.lab.rdu2.dc.redhat.com> Signed-off-by: wang.yuqi <yuqi.wang@daocloud.io>
Signed-off-by: <> Co-authored-by: Varun Sundar Rabindranath <varun-sundar-rabindranath@h100-01.nemg-001.lab.rdu2.dc.redhat.com>
### What this PR does / why we need it? refer to: vllm-project/vllm#40020 , vllm-project/vllm#49152 , vllm-project/vllm#46713 and vllm-project/vllm#49734 , add multi-tier KV cache offloading framework, reusing the c operator from the upstream vllm for batch loading, saving, and searching. ### How was this patch tested? test reuslt: |num-clients/max-active-conversations|base(without offload, TTFT/TPOT)|with dram(TTFT/TPOT)|with dram+ssd(TTFT/TPOT)| | :---:|:---:|:---:|:---:| |8/24|1151.21/87.28|863.02/67.62|605.81/49.87| |16/48|7251.86/108.90|5679.01/83.75|3667.07/59.05| model script: ``` export TP=1 export MODEL_PATH=/nas/disk1/Qwen3-14B export MODEL_NAME=Qwen3-14B export PORT=10113 #export CUDA_VISIBLE_DEVICES=3 export ASCEND_RT_VISIBLE_DEVICES=4 python3 -m vllm.entrypoints.openai.api_server --host 0.0.0.0 --port ${PORT} --dtype bfloat16 --model ${MODEL_PATH} --served-model-name ${MODEL_NAME} --tensor-parallel-size ${TP} --gpu-memory-utilization 0.6 --no-enable-prefix-caching --max-model-len 32768 --trust-remote-code --kv-transfer-config '{ "kv_connector": "OffloadingConnector", "kv_role": "kv_both", "kv_connector_extra_config": { "spec_name": "TieringOffloadingSpec", "cpu_bytes_to_use": 10737418240, "block_size": 128, "eviction_policy": "lru", "secondary_tiers": [ { "type": "fs", "root_dir": "/mnt/kv_cache4", "n_read_threads": 32, "n_write_threads": 16 } ] } }' ``` test script: ``` export MODEL_NAME=/nas/disk1/Qwen3-14B python /model/vllm/benchmarks/multi_turn/benchmark_serving_multi_turn.py --url http://127.0.0.1:10113 --model $MODEL_NAME --served-model-name Qwen3-14B --seed 1234 --input-file /model/vllm/benchmarks/multi_turn/generate_multi_turn2.json \ --num-clients 8 --max-active-conversations 24 ``` generate_multi_turn2.json ``` { "filetype": "generate_conversations", "num_conversations": 96, "text_files": ["pg1184.txt"], "print_stats": false, "prompt_input": { "num_turns": { "distribution": "uniform", "min": 12, "max": 18 }, "common_prefix_num_tokens": { "distribution": "constant", "value": 2000 }, "prefix_num_tokens": { "distribution": "lognormal", "average": 2000, "max": 10000 }, "num_tokens": { "distribution": "uniform", "min": 240, "max": 320 } }, "prompt_output": { "num_tokens": { "distribution": "uniform", "min": 80, "max": 120 } } } ``` - vLLM main: vllm-project/vllm@e6bfe03 --------- Signed-off-by: HF-001 <1670186653@qq.com>
…10575) ### What this PR does / why we need it? refer to: vllm-project/vllm#40020 , vllm-project/vllm#49152 , vllm-project/vllm#46713 and vllm-project/vllm#49734 , add multi-tier KV cache offloading framework, reusing the c operator from the upstream vllm for batch loading, saving, and searching. ### How was this patch tested? test reuslt: |num-clients/max-active-conversations|base(without offload, TTFT/TPOT)|with dram(TTFT/TPOT)|with dram+ssd(TTFT/TPOT)| | :---:|:---:|:---:|:---:| |8/24|1151.21/87.28|863.02/67.62|605.81/49.87| |16/48|7251.86/108.90|5679.01/83.75|3667.07/59.05| model script: ``` export TP=1 export MODEL_PATH=/nas/disk1/Qwen3-14B export MODEL_NAME=Qwen3-14B export PORT=10113 #export CUDA_VISIBLE_DEVICES=3 export ASCEND_RT_VISIBLE_DEVICES=4 python3 -m vllm.entrypoints.openai.api_server --host 0.0.0.0 --port ${PORT} --dtype bfloat16 --model ${MODEL_PATH} --served-model-name ${MODEL_NAME} --tensor-parallel-size ${TP} --gpu-memory-utilization 0.6 --no-enable-prefix-caching --max-model-len 32768 --trust-remote-code --kv-transfer-config '{ "kv_connector": "OffloadingConnector", "kv_role": "kv_both", "kv_connector_extra_config": { "spec_name": "TieringOffloadingSpec", "cpu_bytes_to_use": 10737418240, "block_size": 128, "eviction_policy": "lru", "secondary_tiers": [ { "type": "fs", "root_dir": "/mnt/kv_cache4", "n_read_threads": 32, "n_write_threads": 16 } ] } }' ``` test script: ``` export MODEL_NAME=/nas/disk1/Qwen3-14B python /model/vllm/benchmarks/multi_turn/benchmark_serving_multi_turn.py --url http://127.0.0.1:10113 --model $MODEL_NAME --served-model-name Qwen3-14B --seed 1234 --input-file /model/vllm/benchmarks/multi_turn/generate_multi_turn2.json \ --num-clients 8 --max-active-conversations 24 ``` generate_multi_turn2.json ``` { "filetype": "generate_conversations", "num_conversations": 96, "text_files": ["pg1184.txt"], "print_stats": false, "prompt_input": { "num_turns": { "distribution": "uniform", "min": 12, "max": 18 }, "common_prefix_num_tokens": { "distribution": "constant", "value": 2000 }, "prefix_num_tokens": { "distribution": "lognormal", "average": 2000, "max": 10000 }, "num_tokens": { "distribution": "uniform", "min": 240, "max": 320 } }, "prompt_output": { "num_tokens": { "distribution": "uniform", "min": 80, "max": 120 } } } ``` - vLLM main: vllm-project/vllm@e6bfe03 --------- Signed-off-by: HF-001 <1670186653@qq.com>
…10575) ### What this PR does / why we need it? refer to: vllm-project/vllm#40020 , vllm-project/vllm#49152 , vllm-project/vllm#46713 and vllm-project/vllm#49734 , add multi-tier KV cache offloading framework, reusing the c operator from the upstream vllm for batch loading, saving, and searching. ### How was this patch tested? test reuslt: |num-clients/max-active-conversations|base(without offload, TTFT/TPOT)|with dram(TTFT/TPOT)|with dram+ssd(TTFT/TPOT)| | :---:|:---:|:---:|:---:| |8/24|1151.21/87.28|863.02/67.62|605.81/49.87| |16/48|7251.86/108.90|5679.01/83.75|3667.07/59.05| model script: ``` export TP=1 export MODEL_PATH=/nas/disk1/Qwen3-14B export MODEL_NAME=Qwen3-14B export PORT=10113 #export CUDA_VISIBLE_DEVICES=3 export ASCEND_RT_VISIBLE_DEVICES=4 python3 -m vllm.entrypoints.openai.api_server --host 0.0.0.0 --port ${PORT} --dtype bfloat16 --model ${MODEL_PATH} --served-model-name ${MODEL_NAME} --tensor-parallel-size ${TP} --gpu-memory-utilization 0.6 --no-enable-prefix-caching --max-model-len 32768 --trust-remote-code --kv-transfer-config '{ "kv_connector": "OffloadingConnector", "kv_role": "kv_both", "kv_connector_extra_config": { "spec_name": "TieringOffloadingSpec", "cpu_bytes_to_use": 10737418240, "block_size": 128, "eviction_policy": "lru", "secondary_tiers": [ { "type": "fs", "root_dir": "/mnt/kv_cache4", "n_read_threads": 32, "n_write_threads": 16 } ] } }' ``` test script: ``` export MODEL_NAME=/nas/disk1/Qwen3-14B python /model/vllm/benchmarks/multi_turn/benchmark_serving_multi_turn.py --url http://127.0.0.1:10113 --model $MODEL_NAME --served-model-name Qwen3-14B --seed 1234 --input-file /model/vllm/benchmarks/multi_turn/generate_multi_turn2.json \ --num-clients 8 --max-active-conversations 24 ``` generate_multi_turn2.json ``` { "filetype": "generate_conversations", "num_conversations": 96, "text_files": ["pg1184.txt"], "print_stats": false, "prompt_input": { "num_turns": { "distribution": "uniform", "min": 12, "max": 18 }, "common_prefix_num_tokens": { "distribution": "constant", "value": 2000 }, "prefix_num_tokens": { "distribution": "lognormal", "average": 2000, "max": 10000 }, "num_tokens": { "distribution": "uniform", "min": 240, "max": 320 } }, "prompt_output": { "num_tokens": { "distribution": "uniform", "min": 80, "max": 120 } } } ``` - vLLM main: vllm-project/vllm@e6bfe03 --------- Signed-off-by: HF-001 <1670186653@qq.com>
…10575) ### What this PR does / why we need it? refer to: vllm-project/vllm#40020 , vllm-project/vllm#49152 , vllm-project/vllm#46713 and vllm-project/vllm#49734 , add multi-tier KV cache offloading framework, reusing the c operator from the upstream vllm for batch loading, saving, and searching. ### How was this patch tested? test reuslt: |num-clients/max-active-conversations|base(without offload, TTFT/TPOT)|with dram(TTFT/TPOT)|with dram+ssd(TTFT/TPOT)| | :---:|:---:|:---:|:---:| |8/24|1151.21/87.28|863.02/67.62|605.81/49.87| |16/48|7251.86/108.90|5679.01/83.75|3667.07/59.05| model script: ``` export TP=1 export MODEL_PATH=/nas/disk1/Qwen3-14B export MODEL_NAME=Qwen3-14B export PORT=10113 #export CUDA_VISIBLE_DEVICES=3 export ASCEND_RT_VISIBLE_DEVICES=4 python3 -m vllm.entrypoints.openai.api_server --host 0.0.0.0 --port ${PORT} --dtype bfloat16 --model ${MODEL_PATH} --served-model-name ${MODEL_NAME} --tensor-parallel-size ${TP} --gpu-memory-utilization 0.6 --no-enable-prefix-caching --max-model-len 32768 --trust-remote-code --kv-transfer-config '{ "kv_connector": "OffloadingConnector", "kv_role": "kv_both", "kv_connector_extra_config": { "spec_name": "TieringOffloadingSpec", "cpu_bytes_to_use": 10737418240, "block_size": 128, "eviction_policy": "lru", "secondary_tiers": [ { "type": "fs", "root_dir": "/mnt/kv_cache4", "n_read_threads": 32, "n_write_threads": 16 } ] } }' ``` test script: ``` export MODEL_NAME=/nas/disk1/Qwen3-14B python /model/vllm/benchmarks/multi_turn/benchmark_serving_multi_turn.py --url http://127.0.0.1:10113 --model $MODEL_NAME --served-model-name Qwen3-14B --seed 1234 --input-file /model/vllm/benchmarks/multi_turn/generate_multi_turn2.json \ --num-clients 8 --max-active-conversations 24 ``` generate_multi_turn2.json ``` { "filetype": "generate_conversations", "num_conversations": 96, "text_files": ["pg1184.txt"], "print_stats": false, "prompt_input": { "num_turns": { "distribution": "uniform", "min": 12, "max": 18 }, "common_prefix_num_tokens": { "distribution": "constant", "value": 2000 }, "prefix_num_tokens": { "distribution": "lognormal", "average": 2000, "max": 10000 }, "num_tokens": { "distribution": "uniform", "min": 240, "max": 320 } }, "prompt_output": { "num_tokens": { "distribution": "uniform", "min": 80, "max": 120 } } } ``` - vLLM main: vllm-project/vllm@e6bfe03 --------- Signed-off-by: HF-001 <1670186653@qq.com> Signed-off-by: like-0517 <ithwlike@126.com>
Purpose
TieredOffloading with FS tier on main yields poor performance. This is mostly due to lookup delays triggered by the FSAsyncLookupManager.
We find that the thread backed FSAsyncLookup is severely impacted by the GIL.
Benchmark
This PR:
Test Plan
Added unit tests
Test Result
Unit tests pass