c2892480843s/Qwen3-ForcedAligner-0.6B
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

Qwen3-ForcedAligner-0.6B 在 vLLM-Ascend 0.18.0 上的适配

1. 简介

本文档记录 Qwen3-ForcedAligner-0.6B 在 vLLM-Ascend 0.18.0 环境的适配与验证结果。

Qwen3-ForcedAligner-0.6B 是基于 Qwen3ASRForConditionalGeneration 架构的语音强制对齐模型,核心特点为:

  • 输入:音频 + 参考文本(通过 prompt 传入)
  • 输出:时间戳对齐分类(classify_num: 5000)
  • 与标准 Qwen3ASR 的区别:thinker.lm_head 被替换为 [5000, hidden_size] 的分类头,而非 [vocab_size, hidden_size] 的语言模型头

适配要点:

  • vLLM 已原生支持 Qwen3ASRForConditionalGeneration 架构,但尚未处理 classify_num 场景
  • 本适配通过最小化修改 vllm/model_executor/models/qwen3_asr.py,在检测到 classify_num 时自动将 lm_head 替换为 RowParallelLinear 分类头,并绕过 LogitsProcessor

相关获取地址:

  • 权重下载地址(ModelScope):https://modelscope.cn/models/Qwen/Qwen3-ForcedAligner-0.6B
  • 权重下载地址(AtomGit):https://atomgit.com/Qwen/Qwen3-ForcedAligner-0.6B
  • Docker 镜像(vLLM-Ascend 0.18.0):quay.io/ascend/vllm-ascend:v0.18.0

参考文档:

  • https://docs.vllm.ai/projects/ascend/zh-cn/v0.18.0/tutorials/models/Qwen3ASR.html
  • https://docs.vllm.ai/projects/ascend/zh-cn/v0.18.0/developer_guide/Design_Documents/ACL_Graph.html

2. 验证环境

组件版本
vllm-ascend0.18.0
vllm0.18.0+empty
transformers4.57.6
torch-npu2.9.0.post1+gitee7ba04
cann8.5.1
  • NPU:2 逻辑卡(Ascend910,A2)
  • 模型路径:/tmp/models/Qwen/Qwen3-ForcedAligner-0___6B/
  • 服务端口:8000

3. 代码变更

仅修改 vllm/model_executor/models/qwen3_asr.py,最小化差异如下:

--- a/vllm/model_executor/models/qwen3_asr.py
+++ b/vllm/model_executor/models/qwen3_asr.py
@@ -33,8 +33,10 @@
 
 from vllm.config import ModelConfig, SpeechToTextConfig, VllmConfig
 from vllm.config.multimodal import BaseDummyOptions
+from vllm.distributed import get_pp_group
 from vllm.inputs.data import PromptType, TokensPrompt
 from vllm.logger import init_logger
+from vllm.model_executor.layers.linear import RowParallelLinear
 from vllm.model_executor.models.interfaces import (
     MultiModalEmbeddings,
     SupportsMRoPE,
@@ -312,6 +314,18 @@
                 prefix=maybe_prefix(prefix, "language_model"),
             )
 
+        # ForcedAligner uses a classification head instead of full vocab lm_head
+        self.classify_num = getattr(thinker_config, "classify_num", None)
+        if self.classify_num is not None and get_pp_group().is_last_rank:
+            self.language_model.lm_head = RowParallelLinear(
+                thinker_config.text_config.hidden_size,
+                self.classify_num,
+                bias=False,
+                quant_config=quant_config,
+                prefix=maybe_prefix(prefix, "language_model.lm_head"),
+            )
+            self.language_model.logits_processor = None
+
         self.make_empty_intermediate_tensors = (
             self.language_model.make_empty_intermediate_tensors
         )
@@ -431,6 +445,9 @@
         self,
         hidden_states: torch.Tensor,
     ) -> torch.Tensor | None:
+        if self.classify_num is not None:
+            logits, _ = self.language_model.lm_head(hidden_states)
+            return logits
         return self.language_model.compute_logits(hidden_states)
 
     def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]:

4. 服务启动

已验证通过的启动命令(单卡):

export KERNEL_META_DIR=/tmp/kernel_meta
export ASCEND_CACHE_PATH=/tmp/ascend_cache
export ASCEND_WORK_PATH=/tmp/ascend_work
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True

vllm serve /path/to/Qwen3-ForcedAligner-0.6B \
  --host 0.0.0.0 \
  --port 8000 \
  --dtype bfloat16 \
  --max-model-len 8192 \
  --max-num-seqs 4 \
  --limit-mm-per-prompt '{"audio":1}'

注意:若启动时遇到 Read-only file system: '/vllm-workspace/vllm/kernel_meta',请确保设置可写的 KERNEL_META_DIR 环境变量。

5. Smoke 验证

基础检查:

# 服务就绪检查
curl -sf http://127.0.0.1:8000/v1/models

# 文本推理(分类输出,非自然文本)
curl -sf http://127.0.0.1:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "/path/to/Qwen3-ForcedAligner-0.6B",
    "messages": [{"role": "user", "content": "test"}],
    "temperature": 0,
    "max_tokens": 8
  }'

验证结果:

检查项结果
/v1/models✅ 返回 200
/v1/chat/completions✅ 返回 200,模型可正常前向推理
Dummy weight loading✅ 通过
Real weight loading✅ 通过
ACL Graph capture✅ 通过
音频模态初始化✅ 通过

6. 特性支持矩阵

特性状态说明
文本推理✅分类头输出,需业务层后处理
音频输入✅通过 --limit-mm-per-prompt '{"audio":1}' 启用
多卡并行 (TP)⚠️未验证,理论支持
流水线并行 (PP)⚠️未验证,理论支持
量化 (AWQ/GPTQ)❌框架未支持
Prefix Caching✅默认开启
Chunked Prefill✅默认开启

7. 已知问题与限制

  1. tokenizer regex 警告:当前 tokenizer 存在 Mistral regex 兼容警告,不影响推理功能,可通过后续升级 transformers 或 tokenizer 修复。
  2. 输出后处理:Qwen3-ForcedAligner-0.6B 的 lm_head 输出为 5000 类时间戳分类,需在业务侧实现对应的后处理逻辑(将分类 ID 映射为时间戳),vLLM 层仅负责前向推理。
  3. Transcription API:当前 vLLM 的 transcription endpoint 针对 ASR 设计,ForcedAligner 需通过 chat/completions 传入音频和参考文本使用。

8. 结论

Qwen3-ForcedAligner-0.6B 在 Ascend NPU (A2) 上通过最小化代码修改即可完成适配,核心改动为在 qwen3_asr.py 中支持 classify_num 分类头。模型可正常完成权重加载、ACL Graph 编译与服务启动,基础推理验证通过。