DeepSeek-OCR vLLM 加速部署指南

1. 背景

1.1 目标

将 DeepSeek-OCR 模型从 HuggingFace Transformers 迁移到 vLLM 推理框架,实现加速推理。

1.2 核心挑战

DeepSeek-OCR 是一个自定义多模态模型,包含:

  • 视觉编码器 (SAM + CLIP)
  • 语言模型 (DeepSeek V2/V3)
  • 多模态投影器

vLLM 需要通过自定义模型注册机制来支持它,但 NVIDIA vLLM 镜像使用的是 vLLM 0.11 V1 引擎,与原始代码存在多处 API 不兼容。


2. 环境部署

2.1 启动容器

docker run -d --gpus all \
  --name deepseek-vllm-nvidia \
  --ipc=host \
  -v /your/path/DeepSeek-OCR:/workspace \
  nvcr.io/nvidia/vllm:25.11-py3 \
  sleep infinity

2.2 安装依赖

docker exec deepseek-vllm-nvidia pip install easydict addict matplotlib einops pymupdf img2pdf

3. 模型适配原理

3.1 问题一:cuDNN 引擎兼容性

现象:运行时报错 RuntimeError: GET was unable to find an engine to execute this computation

原因分析

  • GB10 GPU 使用 CUDA 架构 sm_121,是非常新的架构
  • cuDNN 在选择卷积算法时,无法为这个新架构找到合适的实现
  • 错误发生在视觉编码器的 Conv2d 层

解决思路

  • 禁用 cuDNN,让 PyTorch 使用默认的 CUDA 卷积实现
  • deepseek_ocr.py 开头添加 torch.backends.cudnn.enabled = False

影响:可能略微降低卷积性能,但确保兼容性


3.2 问题二:vLLM 0.11 多模态处理器 API 变更

现象:报错 TypeError: got an unexpected keyword argument 'tokenization_kwargs'

原因分析

  • vLLM 0.11 重构了多模态处理器接口
  • _cached_apply_hf_processor 方法新增了 tokenization_kwargsmm_uuids 参数
  • 原始代码使用的是旧版 API 签名

解决思路

  • 更新 DeepseekOCRMultiModalProcessor 类的方法签名
  • 在调用父类方法时传递新参数
  • 修改涉及的方法:_cached_apply_hf_processor, _call_hf_processor

修改文件deepseek_ocr.py 中的 DeepseekOCRMultiModalProcessor


3.3 问题三:compute_logits 接口变更

现象:报错 TypeError: compute_logits() missing 1 required positional argument: 'sampling_metadata'

原因分析

  • vLLM V1 引擎在 profile_run 阶段调用 compute_logits 时只传递 hidden_states
  • 原始实现要求必须传递 sampling_metadata 参数

解决思路

  • sampling_metadata 参数改为可选(默认值 None)
  • 在方法内部判断是否传递了该参数,分别处理

修改文件deepseek_ocr.py 中的 DeepseekOCRForCausalLM.compute_logits 方法


3.4 问题四:设备同步问题

现象:张量运算时偶发设备不匹配错误

原因分析

  • vLLM 使用多进程架构,模型在子进程中初始化
  • 输入张量可能在 CPU 上,而模型在 GPU 上
  • 原始代码假设张量已经在正确设备上

解决思路

  • _pixel_values_to_embedding 方法开头获取模型所在设备
  • 显式将输入张量转移到正确的设备和数据类型

修改文件deepseek_ocr.py 中的 _pixel_values_to_embedding 方法


3.5 问题五:vLLM V1 引擎强制启用

现象:设置 VLLM_USE_V1=0 后报错,提示必须使用 V1

原因分析

  • NVIDIA vLLM 镜像默认且强制使用 V1 引擎
  • V1 引擎的 AsyncLLMEngineLLM 类接口与 V0 不同
  • 无法切换回 V0 引擎

解决思路

  • 接受使用 V1 引擎,适配其 API
  • 使用同步的 LLM 类而非 AsyncLLMEngine
  • 添加必要的 V1 兼容参数

关键配置

  • enforce_eager=True - 禁用 CUDA Graph
  • enable_prefix_caching=False - 禁用前缀缓存
  • enable_chunked_prefill=False - 禁用分块预填充

4. 修改文件清单

文件 修改内容
deepseek_ocr.py 禁用 cuDNN、更新 API 签名、设备同步
run_dpsk_ocr_simple.py 新建图片 OCR 脚本,适配 V1 引擎
run_dpsk_ocr_pdf_simple.py 新建 PDF OCR 脚本,适配 V1 引擎

5. 运行验证

5.1 图片 OCR

docker exec deepseek-vllm-nvidia bash -c "
  cd /workspace/DeepSeek-OCR-master/DeepSeek-OCR-vllm && \
  python3 run_dpsk_ocr_simple.py
"

5.2 PDF OCR

docker exec deepseek-vllm-nvidia bash -c "
  cd /workspace/DeepSeek-OCR-master/DeepSeek-OCR-vllm && \
  python3 run_dpsk_ocr_pdf_simple.py /workspace/document.pdf /workspace/output
"

1 个赞