Skip to content

Commit a27fda1

Browse files
committed
Merge remote-tracking branch 'origin/main' into bsh/dynamic_pd_chunk
# Conflicts: # lightllm/server/router/model_infer/mode_backend/base_backend.py
2 parents 9055c21 + eb2f89b commit a27fda1

41 files changed

Lines changed: 1123 additions & 328 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/CN/source/tutorial/api_server_args.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,6 @@ PD 分离模式参数
267267
输出约束参数
268268
------------
269269

270-
.. option:: --token_healing_mode
271-
272270
.. option:: --output_constraint_mode
273271

274272
设置输出约束后端,可选值:

docs/CN/source/tutorial/multi_level_cache_deployment.rst

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,26 @@ LightLLM 的多级缓存系统采用分层设计:
3737

3838
**工作原理:**
3939

40-
1. 目前的机制是会将GPU cache中的数据原模原样备份一份到CPU cache中,并非只存储GPU cache放不下的内容
40+
1. 缓存放置行为由 ``--cache_placement_strategy`` 控制,可选择兼容旧行为的逐层备份或自适应分层放置
4141
2. L1、L2、L3 cache都基于LRU淘汰策略进行数据管理
4242
3. 为了避免L3缓存频繁写盘,可通过LIGHTLLM_DISK_CACHE_PROMPT_LIMIT_LENGTH环境变量控制写入的最小长度阈值,如果设为0,则所有L2数据都会写入L3缓存
4343
4. 查询时,会先查询L1找出命中的最长前缀,再去L2查询以继续增加最长匹配前缀,最后再去L3查询剩余部分
4444

45+
缓存放置策略
46+
~~~~~~~~~~~~
47+
48+
``--cache_placement_strategy`` 用于选择请求完成后的 KV Cache 放置策略,可选值如下:
49+
50+
- ``adaptive``(默认):冷启动阶段先收集 128 个请求,快速生成 GPU 与低层缓存路径之间的首个长度分界点;之后保留最近 512 个请求的滑动窗口,每 36 个放置步更新一次分界点。短请求放入 GPU,长请求放入 CPU;开启 Disk 时,长请求沿 CPU → Disk 路径异步落盘。由于 Disk 必须经过 CPU,计算比例时低层有效容量取 CPU 与 Disk 容量的较大值,而不是二者之和。默认只使用物理 GPU token 容量的 80% 进行放置估算,为运行态请求预留容量。首次小窗口尚未填满、没有可用分界点时,使用 ``legacy`` 行为完成冷启动。
51+
- ``legacy``:兼容原有的逐层备份行为。请求始终保留在 GPU cache,同时复制到所有已开启的下级缓存;开启 CPU cache 时写入 GPU 和 CPU,同时开启 Disk cache 时写入 GPU、CPU 和 Disk。
52+
53+
未开启 ``--enable_cpu_cache`` 时,该参数不会改变运行行为,所有完成请求都只写入 GPU cache。
54+
55+
.. note::
56+
57+
Disk cache 是通过 CPU cache 异步写入的,因此使用 Disk cache 时仍需同时开启 ``--enable_cpu_cache``。
58+
``LIGHTLLM_DISK_CACHE_PROMPT_LIMIT_LENGTH`` 的最小写盘长度限制对两种策略都生效。
59+
4560
**适用场景:**
4661

4762
- 超长文本处理 (如百万 token 级别的上下文)
@@ -69,7 +84,8 @@ LightLLM 的多级缓存系统采用分层设计:
6984
--mem_fraction 0.88 \
7085
--enable_cpu_cache \
7186
--cpu_cache_storage_size 400 \
72-
--cpu_cache_token_page_size 64
87+
--cpu_cache_token_page_size 64 \
88+
--cache_placement_strategy adaptive
7389
7490
**参数说明:**
7591

@@ -99,6 +115,9 @@ CPU 缓存参数
99115
- 较大的页大小 (如 256) 适合大批量数据迁移,提高传输效率
100116
- 该值需要权衡内存利用率和传输开销
101117

118+
- ``--cache_placement_strategy adaptive``: **缓存放置策略**,默认使用自适应分层;如需保持原有的 GPU + CPU 逐层备份行为,设置为 ``legacy``
119+
- ``LIGHTLLM_CACHE_PLACEMENT_GPU_CAPACITY_RATIO=0.8``: **GPU 容量估算比例**,adaptive 默认使用物理 GPU token 容量的 ``0.8`` 进行放置估算,合法范围为 ``(0, 1]``
120+
102121
**性能优化建议:**
103122

104123
1. **使用 Hugepages**: 执行如下命令并设置环境变量LIGHTLLM_HUGE_PAGE_ENABLE可启用大页模式,启用大页内存可以显著提升服务启动速度,如果觉得服务启动太久可以开启大页模式加速,注意大页模式会长期占据内存空间
@@ -132,6 +151,7 @@ CPU 缓存参数
132151
--enable_cpu_cache \
133152
--cpu_cache_storage_size 400 \
134153
--cpu_cache_token_page_size 256 \
154+
--cache_placement_strategy adaptive \
135155
--enable_disk_cache \
136156
--disk_cache_storage_size 1000 \
137157
--disk_cache_dir /mnt/ssd/disk_cache_dir
@@ -157,6 +177,12 @@ CPU 缓存参数
157177
- 确保目录具有足够的读写权限和磁盘空间
158178
- 注意使用磁盘缓存时, 保证使用的SSD硬盘是长寿命的硬盘, 否则可能会快速消耗其使用寿命。
159179

180+
如需使用兼容旧行为的三级逐层备份策略,将启动参数改为:
181+
182+
.. code-block:: bash
183+
184+
--cache_placement_strategy legacy
185+
160186
相关文档
161187
--------
162188

docs/CN/source/tutorial/reasoning_parser.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,20 @@ GPT-OSS
175175
// 答案块
176176
{"choices": [{"delta": {"content": "答案片段"}}]}
177177
178+
启用 ``--reasoning_parser`` 后,Chat Completions 的 usage 会返回生成的推理
179+
token 数量(不包含推理分隔符):
180+
181+
.. code-block:: json
182+
183+
{
184+
"usage": {
185+
"completion_tokens": 128,
186+
"completion_tokens_details": {"reasoning_tokens": 96}
187+
}
188+
}
189+
190+
Responses API 会在 ``usage.output_tokens_details.reasoning_tokens`` 中返回相同计数。
191+
178192
高级功能
179193
--------
180194

docs/EN/source/tutorial/api_server_args.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,6 @@ Scheduling Parameters
268268
Output Constraint Parameters
269269
----------------------------
270270

271-
.. option:: --token_healing_mode
272-
273271
.. option:: --output_constraint_mode
274272

275273
Set the output constraint backend, optional values:

docs/EN/source/tutorial/multi_level_cache_deployment.rst

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,26 @@ LightLLM's multi-level cache system adopts a hierarchical design:
3737

3838
**Working Principle:**
3939

40-
1. The current mechanism creates an exact backup copy of GPU cache data in CPU cache, not just storing content that doesn't fit in GPU cache
40+
1. Cache placement is controlled by ``--cache_placement_strategy``, which selects either legacy cascading copies or adaptive tier placement
4141
2. L1, L2, and L3 caches all use LRU eviction strategy for data management
4242
3. To avoid frequent disk writes in L3 cache, you can use the LIGHTLLM_DISK_CACHE_PROMPT_LIMIT_LENGTH environment variable to control the minimum length threshold for writes. If set to 0, all L2 data will be written to L3 cache
4343
4. During queries, L1 is checked first to find the longest matching prefix, then L2 is queried to continue extending the longest matching prefix, and finally L3 is queried for the remaining part
4444

45+
Cache Placement Strategies
46+
~~~~~~~~~~~~~~~~~~~~~~~~~~
47+
48+
``--cache_placement_strategy`` controls where completed-request KV Cache is stored:
49+
50+
- ``adaptive`` (default): During cold start, it first collects 128 requests to quickly establish an initial boundary between GPU and the lower-tier cache path. It then keeps a sliding window of the latest 512 requests and updates the boundary every 36 placement steps. Short requests stay on GPU; long requests move to CPU, or follow the asynchronous CPU → Disk path when Disk is enabled. Because Disk must pass through CPU, the effective lower-tier capacity is the larger of CPU and Disk capacity rather than their sum. By default, only 80% of physical GPU token capacity is used for placement estimation, leaving capacity for running requests. Until the initial small window is full and a boundary is available, placement uses ``legacy`` behavior.
51+
- ``legacy``: Preserves the previous cascading-copy behavior. A request always remains in GPU cache and is also copied to every enabled lower tier. Enabling CPU cache stores it in GPU and CPU; enabling Disk cache as well stores it in GPU, CPU, and Disk.
52+
53+
When ``--enable_cpu_cache`` is not enabled, this option does not change runtime behavior and every completed request uses GPU cache only.
54+
55+
.. note::
56+
57+
Disk cache is populated asynchronously through CPU cache, so ``--enable_cpu_cache`` must also be enabled when using Disk cache.
58+
The ``LIGHTLLM_DISK_CACHE_PROMPT_LIMIT_LENGTH`` minimum write threshold applies to both strategies.
59+
4560
**Applicable Scenarios:**
4661

4762
- Ultra-long text processing (e.g., million-token level context)
@@ -69,7 +84,8 @@ Suitable for most scenarios, significantly increasing cache capacity while maint
6984
--mem_fraction 0.88 \
7085
--enable_cpu_cache \
7186
--cpu_cache_storage_size 400 \
72-
--cpu_cache_token_page_size 64
87+
--cpu_cache_token_page_size 64 \
88+
--cache_placement_strategy adaptive
7389
7490
**Parameter Description:**
7591

@@ -99,6 +115,9 @@ CPU Cache Parameters
99115
- Larger page sizes (e.g., 256) are suitable for bulk data migration, improving transfer efficiency
100116
- This value needs to balance memory utilization and transfer overhead
101117

118+
- ``--cache_placement_strategy adaptive``: **Cache placement strategy**. Adaptive tier placement is the default; use ``legacy`` to retain the previous GPU + CPU cascading-copy behavior
119+
- ``LIGHTLLM_CACHE_PLACEMENT_GPU_CAPACITY_RATIO=0.8``: Ratio of physical GPU token capacity used by adaptive placement estimation. The default is ``0.8`` and the valid range is ``(0, 1]``
120+
102121
**Performance Optimization Suggestions:**
103122

104123
1. **Using Hugepages**: Execute the following commands and set the LIGHTLLM_HUGE_PAGE_ENABLE environment variable to enable huge page mode. Enabling huge page memory can significantly improve service startup speed. If you find the service takes too long to start, you can enable huge page mode for acceleration. Note that huge page mode will occupy memory space for the long term
@@ -132,6 +151,7 @@ Suitable for ultra-long text or extremely high-concurrency scenarios, providing
132151
--enable_cpu_cache \
133152
--cpu_cache_storage_size 400 \
134153
--cpu_cache_token_page_size 256 \
154+
--cache_placement_strategy adaptive \
135155
--enable_disk_cache \
136156
--disk_cache_storage_size 1000 \
137157
--disk_cache_dir /mnt/ssd/disk_cache_dir
@@ -156,6 +176,12 @@ In addition to the two-level cache, add the following parameters:
156176
- Strongly recommended to use SSD/NVMe storage, avoid using HDD (performance difference can be 10-100x)
157177
- Ensure the directory has sufficient read/write permissions and disk space
158178

179+
To use the legacy three-level cascading-copy behavior, change the strategy argument to:
180+
181+
.. code-block:: bash
182+
183+
--cache_placement_strategy legacy
184+
159185
Related Documentation
160186
---------------------
161187

docs/EN/source/tutorial/reasoning_parser.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,21 @@ Response Format
175175
// Answer chunk
176176
{"choices": [{"delta": {"content": "Answer fragment"}}]}
177177
178+
When ``--reasoning_parser`` is enabled, Chat Completions usage reports the
179+
number of generated reasoning tokens (excluding reasoning delimiters):
180+
181+
.. code-block:: json
182+
183+
{
184+
"usage": {
185+
"completion_tokens": 128,
186+
"completion_tokens_details": {"reasoning_tokens": 96}
187+
}
188+
}
189+
190+
The Responses API exposes the same count as
191+
``usage.output_tokens_details.reasoning_tokens``.
192+
178193
Advanced Features
179194
-----------------
180195

lightllm/common/basemodel/basemodel.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,7 @@ def __init__(self, kvargs):
8282
self.finetune_config = kvargs.get("finetune_config", None)
8383
self.max_req_num = kvargs.get("max_req_num", 1000)
8484
self.max_seq_length = kvargs.get("max_seq_length", 1024 * 5)
85-
# is_token_healing 和 return_all_prompt_logics 是有排斥关系的两个模式,只能单独有一个生效
86-
# 主要是在prefill阶段返回多少个token的用于后续处理相关。
87-
self.is_token_healing = kvargs.get("is_token_healing", False)
8885
self.return_all_prompt_logics = kvargs.get("return_all_prompt_logics", False)
89-
assert not (self.is_token_healing and self.return_all_prompt_logics), "can not be true in same time"
9086
self.data_type = get_llm_data_type()
9187
self.graph_max_batch_size = kvargs.get("graph_max_batch_size", 16)
9288
self.graph_max_batch_size = (
@@ -387,7 +383,6 @@ def _create_inferstate(self, model_input: ModelInput, microbatch_index: int = 0)
387383
infer_state.hidden_collector = self.hidden_collector_prototype.new_instance()
388384
infer_state.input_ids = model_input.input_ids
389385
infer_state.is_prefill = model_input.is_prefill
390-
infer_state.is_token_healing = self.is_token_healing
391386
infer_state.return_all_prompt_logics = self.return_all_prompt_logics
392387
infer_state.batch_size = model_input.batch_size
393388
infer_state.total_token_num = model_input.total_token_num

lightllm/common/basemodel/infer_struct.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ def __init__(self):
5151

5252
self.mem_index: torch.Tensor = None
5353

54-
self.is_token_healing: bool = False
5554
self.return_all_prompt_logics: bool = False
5655
# 在开启 return_all_prompt_logics 模式时,保存整个 prefill 阶段每一个
5756
# token 位置的 logits,供后续回传 prompt logprobs 信息使用。

lightllm/models/llama/layer_infer/post_layer_infer.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,6 @@ def _norm(self, input, infer_state, layer_weight: LlamaPreAndPostLayerWeight) ->
2323

2424
def _slice_get_last_input(self, input_embdings: torch.Tensor, infer_state: LlamaInferStateInfo):
2525
embed_dim_ = input_embdings.shape[1]
26-
if infer_state.is_prefill and infer_state.is_token_healing:
27-
batch_size = infer_state.batch_size
28-
b_seq_len_numpy = (infer_state.b_seq_len - infer_state.b_ready_cache_len).detach().cpu().numpy()
29-
select_index = []
30-
start_index = 0
31-
select_token_num = 0
32-
for cur_len in b_seq_len_numpy:
33-
select_index.append(start_index + cur_len - 1)
34-
start_index += cur_len
35-
select_token_num += 1
36-
37-
last_index = torch.tensor(select_index, dtype=torch.long, device="cpu").cuda(non_blocking=True)
38-
last_input = self.alloc_tensor((select_token_num, embed_dim_), dtype=input_embdings.dtype, device="cuda")
39-
last_input[:, :] = input_embdings[last_index, :]
40-
return last_input, select_token_num
41-
4226
if infer_state.is_prefill:
4327
# logits 始终只取每个请求最后一个位置的 hidden state,用于正常采样。
4428
batch_size = infer_state.batch_size

lightllm/server/api_cli.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,11 +348,10 @@ def add_cli_args(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
348348
"--short_prefill_token_threshold",
349349
type=int,
350350
default=None,
351-
help="""Enable long/short prefill scheduling and set the maximum remaining tokens of a short request.
351+
help="""Enable short prefill request priority scheduling.
352352
The remaining tokens are calculated after prefix-cache matching. Disabled by default.""",
353353
)
354354
parser.add_argument("--diverse_mode", action="store_true", help="diversity generation mode")
355-
parser.add_argument("--token_healing_mode", action="store_true", help="code model infer mode")
356355

357356
parser.add_argument(
358357
"--output_constraint_mode",
@@ -827,6 +826,16 @@ def add_cli_args(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
827826
default=256,
828827
help="""The token page size of cpu cache""",
829828
)
829+
parser.add_argument(
830+
"--cache_placement_strategy",
831+
type=str,
832+
choices=["adaptive", "legacy"],
833+
default="adaptive",
834+
help="""Cache placement strategy used when CPU cache is enabled.
835+
adaptive: place requests between GPU and the lower-tier cache path based on recent input lengths and capacity;
836+
Disk placement is offloaded through CPU cache, so CPU and Disk capacities are not additive.
837+
legacy: retain GPU cache and also copy each request to every enabled lower cache level.""",
838+
)
830839
parser.add_argument("--enable_disk_cache", action="store_true", help="""enable disk cache to store kv cache.""")
831840
parser.add_argument(
832841
"--disk_cache_storage_size", type=float, default=10, help="""The capacity of disk cache. GB used."""

0 commit comments

Comments
 (0)