
DeepSeek-OCR-2 昇腾 NPU 推理适配实战基于 vLLM-Ascend 的文档 OCR 与 Markdown 输出方案【免费下载链接】cann-recipes-infer本项目针对LLM与多模态模型推理业务中的典型模型、加速算法提供基于CANN平台的优化样例项目地址: https://gitcode.com/cann/cann-recipes-infer本文基于 CANN / cann-recipes-infer 仓库中 integration/vllm/deepseek-ocr-2 目录下的完整适配方案系统讲解 DeepSeek-OCR-2 文档理解模型如何在昇腾 NPUAtlas 800I/T A2上通过 vLLM-Ascend 完成推理部署涵盖一键转换脚本、NPU 运行参数、MOE 算子替换原理、三种推理入口与单卡性能测试方法。读完本文你将掌握从拉取模型到跑通图片/PDF/批量 OCR 推理并产出性能报告的完整闭环流程。方案概览非侵入式 NPU 适配DeepSeek-OCR-2 是 DeepSeek 系列中面向文档理解与 OCR 识别的多模态模型能够将扫描版或版面复杂的图片、PDF 直接识别为结构化 Markdown 文本。本项目基于 vLLM-Ascend 为其提供了一套昇腾 NPU 推理适配方案核心特点如下见 README.mdNPU 原生 MOE 算子支持将模型中的 CUDA 实现替换为 vllm-ascend 的fused_experts非侵入式适配方案不修改官方模型源码主体而是通过补丁脚本注入 NPU 支持模块化设计转换脚本、环境脚本、MOE 补丁、基准测试脚本职责分离易于维护和升级覆盖多种输入形态支持单图、PDF 文档和批量评估结构化 Markdown 输出直接产出可复用的 Markdown 格式识别结果。整个适配任务由智子芯元 KernelCAT 智能体工具自动化完成适配产物即为仓库中的convert_to_npu.sh一键脚本与npu_patch/补丁目录。硬件与基础环境要求项目要求昇腾设备Atlas 800I/T A2内存≥ 32GB磁盘≥ 50GB用于模型存储本项目基于vllm-ascend v0.8.5rc1开发官方提供了配套容器镜像docker pull quay.io/ascend/vllm-ascend:v0.8.5rc1创建容器推荐使用docker run拉起推理容器关键点是透传昇腾设备节点并挂载驱动与模型目录docker run -it -d --nethost --shm-size512g \ --privileged \ --name ds-ocr-2 \ --device/dev/davinci_manager \ --device/dev/hisi_hdc \ --device/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver:ro \ -v /usr/local/sbin:/usr/local/sbin:ro \ -v /data/model_weight:/data \ quay.io/ascend/vllm-ascend:v0.8.5rc1 /bin/bash参数说明--nethost --shm-size512g使用宿主机网络并放大共享内存多模态推理与批量并发场景下避免 IPC 内存不足--privileged与三个--device节点让容器内可见昇腾 NPU 设备davinci_manager、hisi_hdc、devmm_svm-v /usr/local/Ascend/driver:ro以只读方式挂载 NPU 驱动-v /data/model_weight:/data将宿主机模型目录映射到容器内/data后续模型路径按此挂载约定填写。模型获取使用 ModelScope 下载 DeepSeek-OCR-2 权重pip install modelscope -i https://mirrors.huaweicloud.com/repository/pypi/simple # 下载模型 modelscope download --model deepseek-ai/DeepSeek-OCR-2 --local_dir /data/models/DeepSeek-OCR-2参数说明--model模型名称deepseek-ai/DeepSeek-OCR-2--local-dirREADME 中写作--local_dir模型存储路径示例下载到/data/models/DeepSeek-OCR-2该路径即后续config.py中MODEL_PATH的取值。一键转换convert_to_npu.sh 全流程拆解将本项目克隆到容器内/workspace目录cd /workspace git clone https://gitcode.com/cann/cann-recipes-infer.git cd cann-recipes-infer/integration/vllm/deepseek-ocr-2执行转换脚本./convert_to_npu.sh脚本默认参数为./convert_to_npu.sh [source_dir] [target_dir]其中源目录默认为DeepSeek-OCR-2/DeepSeek-OCR2-master/DeepSeek-OCR2-vllm目标目录默认为deepseek_ocr2_npu。结合 convert_to_npu.sh 源码脚本自动完成以下 5 步安装 Python 依赖convert_to_npu.sh L16-L21einops、addict、easydict、triton-ascend、PyMuPDF、img2pdf走华为云 PyPI 镜像加速若个别包安装失败仅告警不中断克隆 DeepSeek-OCR-2 源码convert_to_npu.sh L23-L27若本地不存在SOURCE_DIR则自动git clone --depth1拉取官方源码并定位到 vLLM 工程目录拷贝源码与补丁convert_to_npu.sh L29-L35将官方 vLLM 目录完整复制为deepseek_ocr2_npu/并把 npu_patch/deepseek_ocr2_npu.pyNPU MOE 补丁与 npu_patch/set_env.sh环境初始化放入目标目录应用 NPU 适配补丁convert_to_npu.sh L37-L74注释deepencoderv2/sam_vary_sdpa.py中的flash_attn导入向config.py追加 NPU 配置段并逐一对三个官方推理脚本注入 NPU 支持输出转换结果生成deepseek_ocr2_npu/目录并拷贝 npu_patch/benchmark.py 作为性能测试工具。脚本自动追加的 NPU 配置转换脚本向config.py追加的配置段如下# NPU Configuration DEVICE npu ENFORCE_EAGER True MAX_MODEL_LEN 8192 SWAP_SPACE 0 TENSOR_PARALLEL_SIZE 1 GPU_MEMORY_UTILIZATION 0.85 DISABLE_MM_PREPROCESSOR_CACHE True各参数含义DEVICE npu指定推理设备为昇腾 NPUENFORCE_EAGER True关闭图模式强制 Eager 执行规避 NPU 上算子图捕获兼容性问题这也是 README「适配内容」中强调的 NPU 关键配置MAX_MODEL_LEN 8192模型最大序列长度SWAP_SPACE 0关闭 swap 空间防止出现不可控的 host 内存交换TENSOR_PARALLEL_SIZE 1单卡张量并行对应 README 中「性能测试单卡」的前提GPU_MEMORY_UTILIZATION 0.85NPU 显存利用率DISABLE_MM_PREPROCESSOR_CACHE True关闭多模态预处理器缓存避免多图/PDF 场景缓存命中异常。此外脚本还会对run_dpsk_ocr2_image.py、run_dpsk_ocr2_pdf.py、run_dpsk_ocr2_eval_batch.py三个官方脚本做统一改造在import torch之后注入import os、os.environ[VLLM_USE_V1] 0强制使用 vLLM V0 引擎与import deepseek_ocr2_npu并将所有enforce_eagerFalse统一替换为True、所有gpu_memory_utilization0.75/0.9/0.7统一收敛为0.85。对图片流式脚本还会追加swap_space0与disable_mm_preprocessor_cacheTrue两个引擎参数。环境变量初始化转换完成后进入目标目录并初始化环境cd deepseek_ocr2_npu source set_env.shnpu_patch/set_env.sh 完成三类环境准备CANN 工具链路径设置ASCEND_TOOLKIT_HOME、ASCEND_HOME_PATH、ASCEND_AICPU_PATH、ASCEND_OPP_PATH并优先 source ATBAscend Transformer Boost的set_env.sh缺失时仅告警动态库搜索路径将 driver 的lib64、ascend-toolkit的${ARCH}-linux/lib64与ATB_HOME_PATH/lib依次加入LD_LIBRARY_PATH同时把 CANN Python 包加入PYTHONPATHNPU 运行参数ATB_STREAM_SYNC_EVERY_KERNEL_ENABLE0关闭逐 kernel 流同步以提升性能、ATB_OPSRUNNER_SETUP_CACHE_ENABLE1、HCCL_WHITELIST_DISABLE1、ASCEND_GLOBAL_LOG_LEVEL3、TOKENIZERS_PARALLELISMfalse以及两个关键 vLLM 开关VLLM_ATTENTION_BACKENDNPU显式指定 NPU 注意力后端与VLLM_USE_TRITON_FLASH_ATTN0关闭 Triton FlashAttention配合官方脚本中的 SDPA 路径。运行推理三种入口修改config.py中的三个关键路径参数后即可运行vi config.py # - MODEL_PATH: 模型路径如 /data/models/DeepSeek-OCR-2 # - INPUT_PATH: 输入文件路径 # - OUTPUT_PATH: 输出文件路径三种推理脚本# 图片流式输出 python run_dpsk_ocr2_image.py # PDF 处理 python run_dpsk_ocr2_pdf.py # 图片批量处理 python run_dpsk_ocr2_eval_batch.py注意使用批量处理脚本时config.py中输入图片路径应为图片文件夹路径。三条入口的差异在于输入形态与输出组织单图脚本面向单张图片的流式 Markdown 识别PDF 脚本借助PyMuPDF将 PDF 按页抽取为图片再送入模型批量脚本遍历文件夹内图片适合数据集评估。三者统一复用官方DeepseekOCR2Processor的图像处理管线裁剪模式由CROP_MODE控制并在入口处完成模型注册。NPU 适配原理MOE 算子与注意力机制MOE 算子替换为 vllm-ascend 原生实现DeepSeek-OCR-2 采用 MoEMixture of Experts架构其官方实现依赖 CUDA 的 fused MOE kernel。补丁文件 npu_patch/deepseek_ocr2_npu.py 在导入时执行_apply_moe_patch()实现思路是运行时替换 vllm 的fused_moe符号从vllm_ascend.ops.fused_moe引入fused_experts与select_experts定义ascend_fused_moe(hidden_states, w1, w2, gating_output, topk, renormalize, inplace, **kwargs)包装函数内部先调用select_expertssoftmax 路由打分、top-k 专家选择、可选renormalize再调用fused_experts完成专家前向计算deepseek_ocr2_npu.py L38-L58将包装函数挂载到vllm.model_executor.layers.fused_moe.fused_moedeepseek_ocr2_npu.py L60后续模型前向调用统一走 NPU 原生实现。补丁带完整的降级保护torch_npu、vllm_ascend、vllm任一缺失时仅打印 WARNING 并跳过不会导致导入崩溃便于排查环境问题。注意力机制SDPA 替换 FlashAttention适配内容中明确「注释flash_attn使用 SDPA」。转换脚本通过sed将deepencoderv2/sam_vary_sdpa.py中的from flash_attn行注释掉convert_to_npu.sh L37-L38配合set_env.sh中的VLLM_ATTENTION_BACKENDNPU与VLLM_USE_TRITON_FLASH_ATTN0使注意力计算走 vLLM-Ascend 的 NPU SDPA 后端避免 CUDA 版 FlashAttention 在昇腾上不可用的问题。引擎级参数ENFORCE_EAGERTrue关闭 CUDA Graph 式捕获保证 NPU 上算子稳定执行gpu_memory_utilization0.85为 KV Cache 与多模态中间张量预留合理显存余量。性能测试benchmark.py 使用与指标解读单卡性能测试命令python benchmark.py --image /path/to/image.jpg --concurrent 1,8,16 --warmup 2 --rounds 3参数说明参数说明默认值--image图片文件或目录必填--concurrent并发数列表逗号分隔1,8,16--warmup预热轮数2--rounds测试轮数5--max-tokens最大输出 token8192--gpu-mem显存利用率0.85--output结果输出文件benchmark_results.txt结合 npu_patch/benchmark.py 源码脚本的执行逻辑为图片加载benchmark.py L77-L115单文件图片会复制为 N 份以匹配并发数目录则按jpg/jpeg/png过滤并循环取图请求构造benchmark.py L118-L132调用DeepseekOCR2Processor.tokenize_with_imagesbosTrue, eosTrue, croppingCROP_MODE生成多模态请求采样参数为temperature0.0, max_tokens--max-tokens引擎初始化benchmark.py L161-L176以bfloat16精度加载MODEL_PATH并通过hf_overrides{architectures: [DeepseekOCR2ForCausalLM]}trust_remote_codeTrue注册官方模型类其余参数全部取自config.pyENFORCE_EAGER、MAX_MODEL_LEN、SWAP_SPACE等指标采集benchmark.py L135-L158每个并发档位依次执行 冷启动测试cold→--warmup轮预热 →--rounds轮正式测试统计输出吞吐output_tps 输出 token / 耗时与总吞吐total_tps 输入输出 token / 耗时取均值后打印汇总表并写入--output文件benchmark.py L264-L306资源回收每档并发测试结束即del llm; gc.collect()避免多档位间显存叠加。README 记录的单卡性能数据README「性能数据」一节给出的单卡测试结果如下数据来源于仓库文档记录实际数值以所在环境复测为准并发数输出吞吐 (tokens/s)总吞吐 (tokens/s)140.5096.784106.50292.688212.52584.0232413.681136.8164486.621337.26100550.451512.68可以看到随着并发数从 1 提升到 100输出吞吐从约 40 tokens/s 增长到约 550 tokens/s总吞吐从约 97 tokens/s 增长到约 1513 tokens/s说明该适配方案在批处理维度具备良好的吞吐扩展性。项目结构integration/vllm/deepseek-ocr-2/ ├── convert_to_npu.sh # 一键转换脚本 ├── README.md # 适配说明与部署文档 ├── LICENSE # MIT License └── npu_patch/ ├── deepseek_ocr2_npu.py # NPU MOE 补丁vllm-ascend fused_experts 替换 ├── set_env.sh # 环境初始化CANN/ATB/驱动动态库与 vLLM 开关 └── benchmark.py # 单卡并发性能测试脚本故障排除问题解决方案指定 NPU 设备export ASCEND_RT_VISIBLE_DEVICES0在多卡机器上运行前建议显式指定目标 NPU 设备号其余常见问题可优先检查两点source set_env.sh是否已执行决定 CANN 动态库与VLLM_ATTENTION_BACKENDNPU是否生效、补丁是否随转换脚本注入可在目标目录确认存在deepseek_ocr2_npu.py且官方脚本头部包含import deepseek_ocr2_npu。许可证与第三方代码本项目采用 MIT License 开源许可并包含以下第三方代码详见 README.md 与 LICENSESAMMetaApache License 2.0作为视觉编码器组件DeepSeek-VL2DeepSeek AIMIT LicenseOCR 模型的基础结构来源vLLMApache License 2.0推理框架本体。使用本方案时需一并遵守上述三方组件的许可约束且注意适配依赖 vllm-ascend v0.8.5rc1 与 Atlas 800I/T A2 硬件环境版本或硬件不匹配时需按实际环境重新验证算子兼容性。【免费下载链接】cann-recipes-infer本项目针对LLM与多模态模型推理业务中的典型模型、加速算法提供基于CANN平台的优化样例项目地址: https://gitcode.com/cann/cann-recipes-infer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考