# `offload_group_size` NPU 适配实现计划

> 赛道: CCF 开源创新大赛 vLLM Ascend 参数适配专项赛  
> 参数: `offload_group_size`  
> 状态: 已实现并通过单测、冒烟与 1.5B 参数矩阵测试  
> 日期: 2026-07-06

## 一、需求重述

`offload_group_size` 控制 decoder layer 的分组粒度。vLLM Ascend 需要在模型加载阶段根据该参数划分 layer group，并与 `offload_num_in_group` 配合决定哪些 layer 使用权重 offload。

默认值必须保持兼容：

- `offload_group_size <= 0`: 不启用权重 offload，返回 `NoopOffloader`
- `offload_group_size > 0`: 进入 Ascend offloader 创建流程
- 若 `offload_num_in_group > offload_group_size`: 启动阶段直接报错

## 二、参数语义

对 decoder layers 使用 0-based index 分组：

```text
group_id = layer_id // offload_group_size
offset = layer_id % offload_group_size
```

在 `offload_num_in_group=1` 时，`offload_group_size` 越小，每组越短，被选中的 layer 越密集。

示例：

| num_layers | offload_group_size | offload_num_in_group | selected layers |
|---:|---:|---:|---|
| 8 | 0 | 1 | `()` |
| 8 | 1 | 1 | `(0, 1, 2, 3, 4, 5, 6, 7)` |
| 8 | 2 | 1 | `(1, 3, 5, 7)` |
| 8 | 4 | 1 | `(3, 7)` |

## 三、实现方案

`offload_group_size` 的核心实现集中在：

- `vllm_ascend/model_executor/offloader/selection.py`
- `vllm_ascend/worker/model_runner_v1.py`

`selection.py` 中使用纯函数实现参数语义：

```python
select_offload_layers(
    num_layers=num_layers,
    group_size=offload_group_size,
    num_in_group=offload_num_in_group,
)
```

`model_runner_v1.py` 中通过 `create_ascend_weight_offloader()` 读取配置：

```python
group_size = prefetch_config.offload_group_size
num_in_group = prefetch_config.offload_num_in_group
```

当 `group_size <= 0` 时返回 `NoopOffloader`，确保默认行为不变。

## 四、涉及文件

| 文件 | 说明 |
|---|---|
| `vllm_ascend/model_executor/offloader/selection.py` | 实现 group size 对 layer 分组的影响 |
| `vllm_ascend/model_executor/offloader/sync.py` | 同步 fallback 复用选择结果 |
| `vllm_ascend/model_executor/offloader/prefetch.py` | 预取 offloader 复用选择结果 |
| `vllm_ascend/worker/model_runner_v1.py` | 读取参数并创建 Ascend offloader |
| `tests/model_executor/offloader/offload_group_size/test_param.py` | `offload_group_size` 参数级单测 |

## 五、兼容性

- 默认 `offload_group_size=0` 不改变现有模型加载和推理行为。
- 参数逻辑不依赖真实 NPU，可通过无设备单测验证。
- 实际 offload 执行仍由 sync/prefetch 后端负责，`offload_group_size` 只决定 layer 分组密度。
