vllm
差别
这里会显示出您选择的修订版和当前版本之间的差别。
| 后一修订版 | 前一修订版 | ||
| vllm [2026/08/26 06:40] – 创建 chenyang | vllm [2026/08/26 06:54] (当前版本) – chenyang | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| # vllm | # vllm | ||
| + | |||
| + | |||
| + | ## 🧾一、参数解读 | ||
| vLLM 是用于 LLM 高效推理和服务的高性能框架。以下是其关键启动参数(`vllm serve` 或 `python -m vllm.entrypoints.openai.api_server`)的分类详解: | vLLM 是用于 LLM 高效推理和服务的高性能框架。以下是其关键启动参数(`vllm serve` 或 `python -m vllm.entrypoints.openai.api_server`)的分类详解: | ||
| 行 72: | 行 75: | ||
| ``` | ``` | ||
| + | |||
| + | ## 📝二、张量并行参数取值范围 | ||
| + | |||
| + | |||
| + | `--tensor-parallel-size`(简称 `-tp`)的取值主要受以下 3 个核心规则限制: | ||
| + | |||
| + | ### 1. 必须能被模型的注意力头数整除 | ||
| + | |||
| + | 这是最硬性的数学限制。张量并行会将模型的 Attention 头(Attention Heads)均匀切分到各个 GPU 上。 | ||
| + | |||
| + | * **单头切分限制**:`模型的 num_attention_heads` **必须能被 `-tp` 整除**。例如:若模型的注意力头数为 32,`-tp` 可以设为 1、2、4、8、16、32;但不能设为 3、5、6、7。 | ||
| + | * **GQA / MQA 模型特别注意**:对于采用了分组查询注意力(Grouped-Query Attention)的模型(如 Llama 3、Qwen 2 等),`-tp` 的取值还**必须能被 Key-Value 头数(`num_key_value_heads`)整除**。 | ||
| + | |||
| + | > *例子*:若某模型的 KV Heads 为 8,则 `-tp` 最大只能设为 8(即便总 Head 数是 64),且只能取 1、2、4、8。 | ||
| + | |||
| + | |||
| + | |||
| + | ### 2. 强烈建议为 2 的幂次方(Power of 2) | ||
| + | |||
| + | 虽然理论上只要能整除头数即可(如 6 或 12),但在实际硬件通信中: | ||
| + | |||
| + | * **通信环路与拓扑**:NCCL(NVIDIA 集合通信库)对 2 的幂次方(1、2、4、8)做了极大的传输优化(如 Tree / Ring 算法)。 | ||
| + | * **非 2 的幂次方后果**:使用 3、5、6、7 等卡数会导致显存不均匀分布和严重的跨卡通信开销,推理延迟反而可能比少用一张卡更高。 | ||
| + | |||
| + | ### 3. 尽量控制在单个 NUMA 节点 / 单机(Single Node)内 | ||
| + | |||
| + | `-tp` 在每生成一个 Token 时,跨卡之间都需要进行多次 **All-Reduce** 集合通信,对传输带宽极度敏感。 | ||
| + | |||
| + | * **最佳实践**:`-tp` 的最大值不要超过**单台服务器的物理 GPU 卡数**(通常单机最多 8 卡)。跨卡走 NVLink(如 900 GB/s - 3.2 TB/ | ||
| + | |||
| + | |||
| + | ## 🤴三、注意力头(Attention Head) | ||
| + | |||
| + | |||
| + | **注意力头(Attention Head)** 是 Transformer 模型中 Self-Attention(自注意力机制)的核心组成模块。 | ||
| + | |||
| + | 如果把模型注意力机制比作“看文章”,单个注意力头只能从一种视角去理解文本(例如关注词语之间的**语法关系**);而**多头注意力(Multi-Head Attention)** 允许模型并行使用多个“头”,同时从不同的维度观察上下文(例如头 A 关注**主谓关系**,头 B 关注**代词指代**,头 C 关注**远距离语义关联**)。最后将所有头的输出拼接在一起,形成对文本更全面的理解。 | ||
| + | |||
| + | --- | ||
| + | |||
| + | ### 1. 为什么张量并行(`-tp`)与头数绑定? | ||
| + | |||
| + | 在 GPU 矩阵计算中,多头注意力机制的权重矩阵是**按头(Head)切分**并分配给不同 GPU 的。 | ||
| + | |||
| + | * 每个 GPU 必须分到**完整数量**的头。 | ||
| + | * 例如:模型有 32 个头,如果 `-tp 4`,则每张 GPU 分配得到 $32 \div 4 = 8$ 个头。 | ||
| + | * 如果设置 `-tp 3`,32 无法被 3 整除,GPU 将无法对齐计算矩阵,因此启动会直接报错。 | ||
| + | |||
| + | --- | ||
| + | |||
| + | ### 2. 如何获取模型的注意力头数? | ||
| + | |||
| + | 不需要加载完整模型权重,有以下几种快速获取方式: | ||
| + | |||
| + | #### 方法一:直接查看模型的配置文件(最快、最常用) | ||
| + | |||
| + | 在 Hugging Face 或本地模型目录中,找到 `config.json` 文件: | ||
| + | |||
| + | 1. 打开 `config.json`。 | ||
| + | 2. 查找以下两个核心字段: | ||
| + | * **`num_attention_heads`**(或 `n_head`):模型的总注意力头数(Q 头数)。 | ||
| + | * **`num_key_value_heads`**:KV 头数(**针对 GQA/MQA 模型,`-tp` 必须能被此参数整除**)。 | ||
| + | |||
| + | |||
| + | |||
| + | *例如(Llama-3-8B 的 `config.json` 截取):* | ||
| + | |||
| + | ```json | ||
| + | { | ||
| + | " | ||
| + | " | ||
| + | } | ||
| + | |||
| + | ``` | ||
| + | |||
| + | *在此配置下,`-tp` 的取值必须能够被 `8` 整除(即可以取 1、2、4、8)。* | ||
| + | |||
| + | --- | ||
| + | |||
| + | #### 方法二:使用 Python 代码读取 Config | ||
| + | |||
| + | 无需下载几百吉字节的模型权重文件,只需加载配置对象即可: | ||
| + | |||
| + | ```python | ||
| + | from transformers import AutoConfig | ||
| + | |||
| + | # 替换为你的模型名称或本地路径 | ||
| + | config = AutoConfig.from_pretrained(" | ||
| + | |||
| + | # 获取总 Attention 头数 (Query Heads) | ||
| + | num_heads = getattr(config, | ||
| + | |||
| + | # 获取 KV 头数 (Key/Value Heads, GQA 模型关键参数) | ||
| + | num_kv_heads = getattr(config, | ||
| + | |||
| + | print(f" | ||
| + | print(f" | ||
| + | |||
| + | ``` | ||
| + | |||
| + | --- | ||
| + | |||
| + | #### 方法三:通过 vLLM 启动日志查看 | ||
| + | |||
| + | 如果你直接运行 `vllm serve` 命令,当设置的 `-tp` 无法整除头数时,vLLM 会在终端控制台报错并直接打印出模型的头数信息: | ||
| + | |||
| + | ```bash | ||
| + | ValueError: Total number of attention heads (32) must be divisible by tensor parallel size (3). | ||
| + | ``` | ||
| + | |||
vllm.1787726410.txt.gz · 最后更改: 由 chenyang
