news 2026/9/7 9:41:22

Dify接入昇腾NPU:从Atlas 800到vLLM-Ascend的LLMOps落地全攻略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Dify接入昇腾NPU:从Atlas 800到vLLM-Ascend的LLMOps落地全攻略

简介:面向国产化大模型应用落地场景,这份资源提供基于华为昇腾推理服务器和Atlas300IPro加速卡部署Dify平台的完整可运行源码。压缩包共2个文件,主要包含inscode工程配置与html说明文档,整体仅4KB,却精炼覆盖环境准备、MindIE推理引擎部署、Embedding与Rerank接口验证、Dify v0.8.2安装配置等核心要点。inscode文件便于快速导入运行工程,html页面则直观展示部署过程和运行效果,二者配合可大幅缩短复现路径。已有86人浏览学习,适合正在做昇腾适配、Dify私有化部署或信创AI平台验证的开发者直接参考。借助源码与说明,读者可快速掌握Dify部署全流程中的关键操作与常见排错思路,了解Qwen2.5-7B在双卡环境下的实际运行表现和显存占用情况,从而减少从零摸索带来的试错成本,加速国产化硬件上大模型应用的落地进程。 我接手的那台 Atlas 800 推理服务器,在机房里吃灰了整整两周。驱动、固件、CANN 都装好了,MindIE 也能把 Qwen 跑起来,但业务方一直在问:应用工作台在哪?总不能每次让前端直接对着裸模型接口写代码。于是我把 Dify 平台接到昇腾底座上,整理出一套可以直接跑的完整方案。这篇不写虚的,把可运行源码、核心配置、踩坑记录全部摊开,给同样手里握着 Atlas 机器、想快速落地 LLMOps 的同学一条能直接照抄的路。

先说结论:Dify 本身不需要跑在 NPU 上,昇腾算力通过“模型推理服务”这一层喂给 Dify。看懂这句话,后面所有配置都好理解了。

1. 昇腾环境里跑 Dify,先想清楚算力在哪一层

1.1 Dify 究竟是什么角色

Dify 是开源 LLMOps 平台,聊天助手、Agent、工作流、RAG、数据分析这些能力做得非常顺手,模型接入、提示词管理、知识库、工具调用、日志观测都被集成在一个可视化界面里。

用我自己的话说,Dify 是“模型之上的应用层”,它负责编排和调度,不负责大模型前向推理。这一点非常关键,因为很多人一听“昇腾部署 Dify”,第一反应是给 Dify 容器装 CANN、改 PyTorch 代码,让 Dify 的 Python 服务在 NPU 上跑。方向一开始就错了。Dify 的前端、API、Worker、Sandbox、数据库服务全是常规容器负载,它只需要通过网络去调用一个模型接口,至于这个接口背后是 NVIDIA 显卡还是昇腾 NPU,Dify 根本感知不到。

1.2 昇腾算力的正确位置

真实请求链路是这样的:

链路层组件昇腾上的角色
应用编排层Dify Web / API / Worker / Sandbox普通容器,不碰 NPU
模型接入层OpenAI-API-compatible桥:把昇腾推理服务伪装成 OpenAI API
推理引擎层vLLM-Ascend / MindIE在 NPU 上做真正的模型推理
芯片层Atlas 300I Duo / Atlas 800T A2算力来源

Dify 的模型供应商机制支持任何 OpenAI 兼容接口。昇腾上的 vLLM-Ascend 或者 MindIE 都对外暴露/v1/chat/completions,对 Dify 来说,这就是一个“换了底座和地址的 OpenAI”。你只需要在 Dify 控制台把 Base URL 指向昇腾推理服务,API Key 填任意占位字符串,模型名称填昇腾上部署的模型名,整条链路就通了。

1.3 正确部署顺序

先起 Dify 本体,包括 PostgreSQL、Redis、API、Worker、Web、Sandbox,再在 Atlas 机器上起模型服务,最后在 Dify 控制台把 Base URL 指过去。

这个顺序有讲究。如果先配模型再接平台,一旦出问题,你根本分不清是 Dify 配置错了,还是推理服务没起来。先把两头各自验证通,再接中间,一次成功的概率会高很多。我自己第一次做的时候就是先在一个裸容器里把 vLLM-Ascend 跑通,curl 验证完模型接口,才开始碰 Dify。

2. 环境准备:驱动、CANN、容器运行时,版本和挂载一步都不能错

2.1 先认清手里是哪一类昇腾硬件

“昇腾系列有哪些 GPU”这个问题被问过太多次。先纠正叫法:昇腾的算力芯片不叫 GPU,叫 NPU。常见型号差别很大,直接影响你能跑什么规模的模型。

型号形态显存适合场景
Atlas 300I Duo半高推理卡16GB / 48GB 版本7B~13B 模型推理
Atlas 300V Pro视频/视觉推理卡较小视频解码、CV 场景,不适合长文本 LLM
Atlas 800 推理服务器(型号 9000)整机,插多张 300I Duo按卡累计企业级并发推理
Atlas 800T A2 训练服务器训练整机单卡 64GB 级别大模型训练,也适合 14B 以上推理

我实测用的是 Atlas 800 推理服务器,两张 300I Duo 48GB。跑 Qwen2.5-7B-Instruct 非常从容,max-model-len 给到 8192 也不紧张,单卡并发处理 20 个左右请求问题不大。

2.2 版本配套宁可多查一遍

昇腾软件栈的版本要求比 NVIDIA 严格得多。驱动、固件、CANN、torch_npu、容器运行时必须在一个配套表里面,否则装出来会非常诡异:有时驱动能看见卡,但 CANN 一申请显存就报错;有时 CANN 版本没问题,但 docke 容器里挂载设备路径不对,又浪费半天。

我用的组合是驱动/固件 23.0.6 + CANN 8.0.RC1。拿到机器先验证:

npu-smi info cat /usr/local/Ascend/ascend-toolkit/latest/version.cfg

npu-smi info能看到卡的状态和显存总量,version.cfg能看到 CANN 版本。新机器开箱后,第一件事就是去昇腾社区官网查“驱动-固件-CANN 配套表”,别嫌麻烦,这一步帮你省下后面至少两天的排查时间。

2.3 容器里必须能看到 NPU,否则后面全白搭

Docker 默认不会把 NPU 设备映射进容器。华为提供了 ascend-docker-runtime,装好之后执行docker info | grep -i runtime,能看到一个叫ascend的 runtime。

如果没有这个 runtime,就必须在docker run时手动带设备和目录:

docker run --rm \ --device=/dev/davinci0 \ --device=/dev/davinci_manager \ --device=/dev/hisi_hdc \ --device=/dev/devmm_svm \ -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \ -v /usr/local/dcmi:/usr/local/dcmi \ -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ ascend/vllm-ascend:latest \ npu-smi info

先跑通这条最小命令,再进下一步。如果容器里看不到davinci0,说明设备挂载或 runtime 有问题,这时候去排查 Dify 没有任何意义。

提示:宿主机上npu-smi正常不代表容器里正常。容器缺设备映射时,最常见的报错是No such file or directoryCan't open device

3. 模型服务层:用 vLLM-Ascend 拉起 OpenAI 兼容接口

3.1 为什么选 vLLM-Ascend,而不是 MindIE

MindIE 是华为原生的推理引擎,性能和昇腾硬件贴合度都很高,但配置流程明显更重:权重要转换、版本要严格对应、文档相对分散。vLLM-Ascend 是社区在标准 vLLM 上加的 Ascend 后端,使用习惯和 NVIDIA 生态几乎一致,出了问题也更容易在社区里找到答案。

如果目标是“赶紧把 Dify 跑起来”,vLLM-Ascend 是更顺的路。MindIE 更适合在生产环境做极致性能优化。不过两者对 Dify 来说没有任何区别,都是 OpenAI 兼容 API,后面 Base URL 的端口不一样而已。

3.2 装环境、下模型、起服务

准备一个 Python 3.10 环境:

conda create -n vllm-ascend python=3.10 -y conda activate vllm-ascend pip install vllm==0.8.4 vllm-ascend==0.8.4

注意,vllm-ascend 对 CANN 版本有要求,装之前先看它的 release 说明。我这边 CANN 8.0.RC1 配合这两个版本没有问题。

模型用 ModelScope 下载,内网服务器拉取速度快:

pip install modelscope modelscope download --model Qwen/Qwen2.5-7B-Instruct --local_dir /data/models/Qwen2.5-7B-Instruct

然后启动推理服务:

export ASCEND_RT_VISIBLE_DEVICES=0 vllm serve /data/models/Qwen2.5-7B-Instruct \ --host 0.0.0.0 \ --port 8000 \ --dtype bfloat16 \ --max-model-len 8192 \ --gpu-memory-utilization 0.9 \ --tensor-parallel-size 1

参数解读:

  • ASCEND_RT_VISIBLE_DEVICES=0:指定进程用哪张卡,作用类似CUDA_VISIBLE_DEVICES
  • --dtype bfloat16:昇腾对 BF16 支持依赖 CANN 版本,老版本或部分边缘推理卡不支持时就改成float16
  • --gpu-memory-utilization 0.9:默认就是 0.9。7B 模型 BF16 权重约 14GB,48GB 卡上模型加 KV Cache 完全够。16GB 小卡要往下调,同时缩短--max-model-len
  • --tensor-parallel-size 1:单卡先跑通,多卡并行要处理 HCCL 通信,排障顺序不要反。

3.3 验证模型服务

curl http://localhost:8000/v1/models curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "Qwen2.5-7B-Instruct", "messages": [{"role": "user", "content": "你好"}] }'

返回正常的 completion 结果,说明模型服务已经能对外服务了。到这一步,昇腾侧的核心链路就通了,接下来可以安心部署 Dify。

4. Dify 平台部署:裁剪后的最小可运行 compose

4.1 为什么裁剪官方 compose

官方 docker compose 里服务非常多,API、Worker、Web、PostgreSQL、Redis、Sandbox、SSRF 代理、Plugin Daemon、向量库,样样都有。新手直接照搬,容易出现某个服务版本冲突,或者一堆根本用不上的组件占用资源。

我这边裁剪出一套最小闭环:PostgreSQL、Redis、Sandbox、SSRF Proxy、Plugin Daemon、Migration、API、Worker、Web。向量存储先用pgvector,后续要接外部 Qdrant 再改配置。镜像版本以官方当前最新 release 为准,这里用 1.10.1 作为示例。

4.2 可运行 docker-compose

version: "3.9" x-common-env: &common-env DB_HOST: postgres DB_PORT: 5432 DB_USERNAME: dify DB_PASSWORD: dify DB_DATABASE: dify REDIS_HOST: redis REDIS_PORT: 6379 SECRET_KEY: change-me-to-a-long-random-string VECTOR_STORE: pgvector CODE_EXECUTION_ENDPOINT: http://sandbox:8194 CODE_EXECUTION_API_KEY: dify-sandbox SSRF_PROXY_HTTP_URL: http://ssrf_proxy:3128 SSRF_PROXY_HTTPS_URL: http://ssrf_proxy:3128 PLUGIN_DAEMON_URL: http://plugin_daemon:5002 PLUGIN_DAEMON_KEY: change-me-plugin-key PLUGIN_DAEMON_REQUEST_TIMEOUT: 120 services: postgres: image: postgres:15-alpine environment: POSTGRES_USER: dify POSTGRES_PASSWORD: dify POSTGRES_DB: dify volumes: - pg_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U dify"] interval: 5s timeout: 5s retries: 10 restart: always redis: image: redis:7-alpine volumes: - redis_data:/data restart: always sandbox: image: langgenius/dify-sandbox:latest environment: API_KEY: dify-sandbox GIN_MODE: release restart: always ssrf_proxy: image: langgenius/dify-ssrf-proxy:latest restart: always plugin_daemon: image: langgenius/dify-plugin-daemon:0.0.9 environment: DB_PLUGIN_HOST: postgres DB_PLUGIN_PORT: 5432 DB_PLUGIN_USERNAME: dify DB_PLUGIN_PASSWORD: dify DB_PLUGIN_DATABASE: dify REDIS_PLUGIN_HOST: redis REDIS_PLUGIN_PORT: 6379 PLUGIN_DAEMON_KEY: change-me-plugin-key PLUGIN_DAEMON_PORT: 5002 ports: - "5002:5002" restart: always migration: image: langgenius/dify-api:1.10.1 depends_on: postgres: condition: service_healthy redis: condition: service_started environment: *common-env command: ["flask", "db", "upgrade"] restart: "no" api: image: langgenius/dify-api:1.10.1 depends_on: postgres: condition: service_healthy redis: condition: service_started migration: condition: service_completed_successfully environment: <<: *common-env MODE: api ports: - "5001:5001" volumes: - storage:/app/api/storage restart: always worker: image: langgenius/dify-api:1.10.1 depends_on: postgres: condition: service_healthy redis: condition: service_started migration: condition: service_completed_successfully environment: <<: *common-env MODE: worker volumes: - storage:/app/api/storage restart: always web: image: langgenius/dify-web:1.10.1 depends_on: - api ports: - "3000:3000" restart: always volumes: pg_data: redis_data: storage:

启动命令很简单:

mkdir -p /opt/dify-ascend cd /opt/dify-ascend vim docker-compose.yml docker compose up -d docker compose ps

如果本地 Docker Compose 版本比较老,不支持condition: service_completed_successfully,就先去掉 migration 依赖,手动执行docker compose exec api flask db upgrade,再启动 api 和 worker。

4.3 Dify 和模型服务怎么通信

Compose 里的 Dify 各服务在默认 bridge 网络里。vLLM-Ascend 如果在宿主机上直接跑,Dify 容器访问宿主机局域网 IP 即可;如果模型服务跑在另一台 Atlas 机器上,Dify 容器访问那台机器的局域网 IP 即可。

注意:Base URL 千万别写localhost。容器里没有宿主机意义上的 localhost,写了必挂。我见过太多人卡在这个问题上。

5. 接入昇腾模型:控制台配置 OpenAI-API-compatible

5.1 添加模型供应商

登录 Dify 控制台,进入“设置 → 模型供应商”,添加OpenAI-API-compatible类型的供应商。要填的字段如下:

字段
Base URLhttp://192.168.1.100:8000/v1
API Key任意字符串,例如 ascend-local
模型类型LLM
模型名称Qwen2.5-7B-Instruct

填写之后点“测试”,连接成功就可以保存。

这个配置的本质就是让 Dify 把昇腾推理服务当成一个 OpenAI 兼容的第三方平台。API Key 填什么不重要,因为 vLLM-Ascend 默认不校验,但它要求这个字段非空,所以给一个占位字符串即可。

5.2 先跑通一个最小聊天应用

创建一个“聊天助手”应用,在提示词编排页面右上角把模型切到刚接入的昇腾模型,发送消息。如果正常返回,这条“昇腾推理 → Dify 编排 → 用户对话”的链路就算通了。

到这里,整个部署已经成功。但实际使用中,你大概率不只是想要一个聊天框,而是想基于昇腾模型的能力,做一个真正能落地的应用。

5.3 升级成数据分析 Agent

很多人搜“dify 搭建数据分析平台”,其实昇腾上的大模型完全能撑起这个场景。做法是:在 Dify 创建一个 Agent 应用,给 Agent 添加一个 SQL 执行工具,把数据库连接信息配好,然后用户用自然语言提问,模型负责把问题转成 SQL、执行查询、总结结果。

这套方案跑在 Atlas 上,模型本地部署、数据不出内网,对数据敏感场景很有价值。部署步骤不会因为加了 Agent 而变化,模型还是那一个,工具调用由 Dify 的 Agent 编排机制接管,昇腾推理服务只负责生成 token,不需要知道自己正在帮用户写 SQL。

6. 实测踩坑:从 NPU 设备映射到对话 400,四个高频问题

6.1 坑一:Dify 容器里访问不到模型服务

表现:模型供应商测试失败,但宿主机上 curl vLLM 接口完全正常。

排查链路:

  1. 宿主机执行curl http://localhost:8000/v1/models,返回正常。
  2. docker compose exec api curl http://127.0.0.1:8000/v1/models,连接失败。
  3. 意识到localhost127.0.0.1在容器里只代表 Dify 容器自身,不是宿主机。
  4. 把 Base URL 改成http://<宿主机局域网IP>:8000/v1,测试通过。

这个坑跟昇腾关系不大,但在异构部署里非常典型。记住一条规则:容器里的localhost永远只代表容器自身。

6.2 坑二:容器里看不到 NPU 卡

表现:vLLM-Ascend 启动时报davinci0不存在,或者容器内执行npu-smi info没有任何输出。

排查链路:

  1. 宿主机执行npu-smi info,正常显示卡信息,说明驱动没问题。
  2. 执行docker info | grep -i runtime,发现没有 ascend runtime。
  3. 安装 ascend-docker-runtime,并在启动容器时指定--runtime ascend
  4. 容器内再执行npu-smi info,一切正常。

教训:不要在容器启动参数上省时间。先跑一个最小验证镜像,确认容器内能看到 NPU,再去跑 vLLM、Dify 这些上层应用,否则问题会被层层包装成各种莫名其妙的报错。

6.3 坑三:vLLM-Ascend 启动时显存不够

表现:启动时报No available memory for the cache,或者模型起来了但对话一长就报超长。

排查链路:

  1. npu-smi info查看单卡 HBM 总量和当前占用。
  2. 估算权重占用:7B BF16 约 14GB,14B BF16 约 28GB。
  3. 如果 48GB 卡连一个 7B 都跑不起来,检查ASCEND_RT_VISIBLE_DEVICES是否指向了一张已经被别的进程占用的卡。
  4. 适当缩小--max-model-len,比如从 8192 降到 4096,KV Cache 占用会明显降低。

经验是:先保证模型服务自身有余量,再谈并发。7B 模型在 48GB 单卡上开 8K context,留 0.9 的显存利用率,日常测试完全够用;真要上生产,再根据并发峰值做压测。

6.4 坑四:连接成功但对话报 400

表现:模型供应商测试通过,应用内对话却报 400 或者一直转圈。

排查链路:

  1. 执行docker compose logs -f api,日志里大概率有上游推理服务返回的 4xx 信息。
  2. 检查 Dify 里填的“模型名称”和 vLLM 端实际部署的模型名是否一致。
  3. 检查请求 token 数是否超过 vLLM 的--max-model-len
  4. 在生产环境中,建议给 vLLM 显式指定--served-model-name Qwen2.5-7B-Instruct,Dify 里填同样的名称,两个服务之间的模型名就永远对齐了。

这四个坑基本覆盖了我第一次打通昇腾 Dify 链路时遇到的主要问题。解决之后,整条链路稳了很多,后面就是按团队加权限、接企业知识库、做更复杂的 Agent 编排这些业务层面的演进,已经不属于部署链路的范畴。

最后分享一个生产小技巧:把 vLLM-Ascend 的启动命令封装成一个 systemd unit,机器重启后自动拉起。Dify 那边只要 Base URL 不变,模型供应商配置就完全不用动。昇腾 Dify 这套组合跑起来之后,团队里不懂部署的人也能通过界面搭 Agent,这才是平台化部署真正的价值。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 9:40:40

相机标定实战:张正友标定法配合OpenCV从棋盘格到内参全解

简介&#xff1a;一份基于OpenCV实现张正友相机标定的完整工程资源&#xff0c;面向需要学习相机标定原理与工程实现的开发者、研究人员&#xff0c;解决从标定板制作、图像采集到相机内外参计算与畸变矫正的全流程问题。压缩包共107个文件&#xff0c;大小约95.67MB&#xff0…

作者头像 李华
网站建设 2026/9/7 9:39:23

动力电池CCS设计全解析:从概念区分到工程验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 9:39:18

WPS正则表达式三入口:通配符、VBA与JS宏引擎差异详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 9:38:42

规则集启用后为什么不生效?完整指南

规则集启用后为什么不生效&#xff1f;完整指南 【免费下载链接】docs The open-source repo for docs.github.com 项目地址: https://gitcode.com/GitHub_Trending/do/docs 规则集(Ruleset)显示"已启用"&#xff0c;推送却照样通过、合并照样被拦&#xff0c…

作者头像 李华
网站建设 2026/9/7 9:38:02

WPF ListBox拖拽实战:从事件路由到MVVM数据绑定的完整指南

简介&#xff1a;面向WPF初中级开发者的拖拽交互示例包&#xff0c;围绕两个ListBox之间的Drag & Drop功能展开&#xff0c;涵盖跨列表移动元素、上下按钮调整顺序、拖动时改变边框颜色等常见交互场景。包内共37个文件&#xff0c;以cs源码、xaml界面定义为主&#xff0c;并…

作者头像 李华
网站建设 2026/9/7 9:35:26

C标准库源码深度拆解:从malloc到printf的内存与格式化底层原理

简介&#xff1a;面向 C/C 学习者和系统程序员的 C 标准库源代码包&#xff0c;完整覆盖标准输入输出、字符串处理、内存管理、数学运算、时间日期及文件系统接口等模块&#xff0c;解决深入理解库函数底层实现与 C 语言运行机制的学习需求。整个压缩包共 1266 个文件&#xff…

作者头像 李华