拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

昇腾NPU实战:Qwen2.5-7B-Instruct在AtomGit环境下的硬核部署与稳定性测评(TaoToken统一Key接入版)

昇腾NPU实战:Qwen2.5-7B-Instruct在AtomGit环境下的硬核部署与稳定性测评(TaoToken统一Key接入版) 1. 昇腾 NPU 上跑 Qwen2.5-7B-Instruct为什么还要接一层统一 KeyAtomGit 的 Notebook 把昇腾 910B 的算力门槛拉得很低选个 NPU 镜像就能进 JupyterLabnpu-smi info一敲就能看到 Atlas 800T 的卡。但真正把 Qwen2.5-7B-Instruct 跑起来之后很多人会卡在第二个问题上模型在 Notebook 里能对话了可我在本地 VS Code、Cline、CC Switch 这些工具里怎么调它总不能在 Notebook 里手写 requests 吧。我这次的做法是AtomGit 负责算力和模型推理TaoToken 负责统一 Key 和 API 通道。也就是说昇腾 NPU 上跑一个 OpenAI 兼容的推理服务本地编码工具通过 TaoToken 的 API 通道去访问。这样一套 Key 可以同时管模型对话、Coding Plan 和接入文档里的各种客户端不用每换一个工具就重新配一遍地址和密钥。这篇内容适合三类人手里有 AtomGit 昇腾资源、想把 Qwen2.5-7B-Instruct 跑成可调用服务的开发者用 Cline 或 CC Switch 做日常编码、想接国产算力后端的同学以及需要量化长时运行稳定性、不想只跑一次 demo 就交差的人。下面从环境验证、Torch-NPU 推理脚本、config.toml 与 settings.json 骨架到压测和报错排查一步步走完。2. TaoToken 前置统一 Key 与 API 通道准备在昇腾侧把模型跑通之前先把 TaoToken 这边的通道准备好后面本地工具接入会顺很多。TaoToken 的定位是统一 Key 管理加 API 通道官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基础地址是 https://taotoken.net/api 注意这个地址后面不加 UTM 参数。你需要做的第一件事是拿到 API Key。进控制台的 API Keys 页面创建一个建议按用途命名比如atomgit-npu-qwen方便后面在多个工具里区分。创建之后把 Key 复制到安全的地方它只会完整显示一次。第二步是确认你要用哪种接入方式。如果你只是想在本地快速验证模型对话效果用模型对话页面最直接如果你是要长期做编码、跑 Agent 任务那 Coding Plan 更合适它按周期计费适合高频调用如果你要接 Cline、CC Switch 这类客户端那就走 API Keys 加接入文档的组合。这里有个容易混淆的点TaoToken 不是模型本身它不替代 AtomGit 的算力也不替代你本地的编辑器。它做的是把请求统一转发到你配置的后端通道上。所以昇腾 NPU 上的推理服务地址、端口、模型名这些还是要你自己在 AtomGit 侧维护好。TaoToken 负责的是 Key 的统一管理和客户端侧的标准化接入。注意API Key 不要写进会提交到 Git 的配置文件里。建议用环境变量或者本地.env文件并且把.env加进.gitignore。3. 可复制配置AtomGit 侧推理服务与本地工具骨架3.1 AtomGit 昇腾环境验证与依赖安装进 AtomGit Notebook 之后镜像选euler2.9-py38-torch2.1.0-cann8.0-openmind0.6-notebook计算资源选NPU basic · 1 * NPU 910B · 32v CPU · 64GB。启动后在终端先做三件事。第一确认 NPU 物理状态npu-smi info看到 Atlas 800T 的卡信息和空载显存就对了。第二验证 PyTorch 与 torch_npu 的适配python -c import torch; print(torch.__version__) python -c import torch_npu; print(torch_npu.__version__) python -c import torch, torch_npu; print(torch.npu.is_available())第三条必须返回True否则后面devicenpu会直接报错。第三升级 transformers 和 accelerateQwen2.5 需要 transformers 大于 4.37pip install --upgrade transformers accelerate -i https://pypi.tuna.tsinghua.edu.cn/simple模型下载用 Git LFS 从 ModelScope 克隆比 Python 库在 py38 下更稳git lfs install mkdir -p models/Qwen git clone https://www.modelscope.cn/Qwen/Qwen2.5-7B-Instruct.git ./models/Qwen/Qwen2.5-7B-Instruct断了就进目录git lfs pull续传。3.2 昇腾侧 OpenAI 兼容服务脚本光有inference_npu.py只能本地跑要让 TaoToken 通道能转发过来得把推理包成一个 HTTP 服务。下面这个serve_npu.py用 FastAPI 暴露一个/v1/chat/completions接口格式对齐 OpenAI这样本地工具不用改协议。import torch import torch_npu from fastapi import FastAPI from pydantic import BaseModel from transformers import AutoTokenizer, AutoModelForCausalLM import uvicorn DEVICE npu MODEL_PATH ./models/Qwen/Qwen2.5-7B-Instruct app FastAPI() tokenizer AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained( MODEL_PATH, device_mapDEVICE, torch_dtypetorch.bfloat16, trust_remote_codeTrue ) model.eval() class ChatRequest(BaseModel): model: str qwen2.5-7b-instruct messages: list max_tokens: int 512 temperature: float 0.7 app.post(/v1/chat/completions) def chat(req: ChatRequest): text tokenizer.apply_chat_template( req.messages, tokenizeFalse, add_generation_promptTrue ) inputs tokenizer([text], return_tensorspt).to(DEVICE) with torch.no_grad(): out model.generate( **inputs, max_new_tokensreq.max_tokens, do_samplereq.temperature 0, temperaturereq.temperature ) torch.npu.synchronize() gen out[0][inputs.input_ids.shape[1]:] content tokenizer.decode(gen, skip_special_tokensTrue) return { choices: [{message: {role: assistant, content: content}}] } if __name__ __main__: uvicorn.run(app, host0.0.0.0, port8000)启动python serve_npu.py服务起来后AtomGit 侧就有一个http://0.0.0.0:8000/v1的 OpenAI 兼容端点了。3.3 本地 config.toml 与 settings.json 骨架本地工具接入 TaoToken 时核心是填对 base_url 和 api_key。下面给两个骨架。config.toml适合支持 TOML 配置的客户端[provider.taotoken] base_url https://taotoken.net/api api_key sk-你的TaoTokenKey model qwen2.5-7b-instruct timeout 120 [provider.taotoken.headers] X-Backend atomgit-npusettings.json适合 VS Code 系插件或 Cline{ taotoken.baseUrl: https://taotoken.net/api, taotoken.apiKey: sk-你的TaoTokenKey, taotoken.model: qwen2.5-7b-instruct, taotoken.maxTokens: 2048, taotoken.temperature: 0.7 }Cline 接入片段在 Cline 的设置里选 OpenAI CompatibleBase URL 填https://taotoken.net/apiAPI Key 填你的 TaoToken KeyModel ID 填qwen2.5-7b-instruct。保存后 Cline 的请求就会走 TaoToken 通道。CC Switch 接入片段在 CC Switch 里新增一个 provider类型选 OpenAI 兼容地址同上Key 同上。CC Switch 的好处是可以在多个 provider 之间快速切换比如白天用 Coding Plan晚上切回按量通道。注意X-Backend这个 header 是我自己加的标记用来在日志里区分请求来源不是 TaoToken 的必填项。你可以按自己的习惯改。4. 验证请求与成功结果配置写完先别急着上工具用 curl 在本地验证一次确认通道是通的。curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer sk-你的TaoTokenKey \ -H Content-Type: application/json \ -d { model: qwen2.5-7b-instruct, messages: [{role: user, content: 用一句话解释什么是快速排序}], max_tokens: 128 }如果返回里有choices[0].message.content且内容是通顺的中文说明 TaoToken 通道和昇腾侧服务都通了。接着在 AtomGit 侧看日志确认请求确实打到了 NPU 上。serve_npu.py的 uvicorn 日志会打印 POST 记录同时你可以另开一个终端跑watch -n 1 npu-smi info请求进来时显存占用会从空载跳到 14GB 左右推理结束后回落。这个跳变就是 NPU 真实参与计算的证据。再跑一次同样的 curl对比两次耗时。第一次通常 30 秒上下因为包含算子编译第二次会降到几秒。这个差异是昇腾 JIT 编译的正常表现不是通道慢。5. 本篇常见错排查5.1 NPU out of memory 但显存看着还有空报错长这样RuntimeError: NPU out of memory. Tried to allocate 21.68 GiB (NPU 0; 60.97 GiB total capacity; 44.94 GiB already allocated...)这是内存碎片导致的不是真的没显存。加环境变量限制切分块大小export PYTORCH_NPU_ALLOC_CONFmax_split_size_mb:128然后重启服务。如果还不行把 batch size 降一档或者把max_new_tokens从 512 降到 256 试试。5.2 首次推理极慢或看起来卡死昇腾的算子编译机制决定的。第一次遇到某个输入 shapeCANN 要现场编译计算图几十秒很正常。解决办法是在服务启动后先跑一次 warmupdummy tokenizer(Hello, return_tensorspt).to(DEVICE) model.generate(**dummy, max_new_tokens20) torch.npu.synchronize()warmup 之后相同 shape 的请求就会走缓存速度稳定。生产环境建议用分桶策略把输入长度固定到 128、512、1024 几个档位避免频繁触发编译。5.3 ImportError: cannot import name TeQuantizertransformers 版本太老跟 Qwen2.5 的代码不匹配。直接升级pip install --upgrade transformers -i https://pypi.tuna.tsinghua.edu.cn/simple升级后重启 Python 进程不要只重启服务因为模块已经加载进内存了。5.4 TaoToken 侧返回 401 或 403先检查 Key 有没有复制完整前后有没有多余空格。然后确认请求头是Authorization: Bearer sk-xxx不是X-API-Key。如果 Key 是在控制台刚创建的等几秒再试有时候有短暂的生效延迟。5.5 本地工具连不上但 curl 能通大概率是工具的 base_url 填错了。TaoToken 的 API 地址是https://taotoken.net/api有些工具会自动补/v1有些不会。如果工具里填的是https://taotoken.net/api/v1而工具又自动补了一次就会变成/v1/v1。建议先按工具文档填报错再调整。6. 长时运行稳定性压测与量化跑通只是起点真正要交付的是长时运行表现。下面这个压测脚本在昇腾侧跑模拟连续请求记录 TPS 和峰值显存。import torch import torch_npu from transformers import AutoTokenizer, AutoModelForCausalLM import time DEVICE npu MODEL_PATH ./models/Qwen/Qwen2.5-7B-Instruct tokenizer AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained( MODEL_PATH, device_mapDEVICE, torch_dtypetorch.bfloat16, trust_remote_codeTrue ) # warmup dummy tokenizer(Hello, return_tensorspt).to(DEVICE) model.generate(**dummy, max_new_tokens20) torch.npu.synchronize() prompt 请详细介绍昇腾 NPU 的架构特点不少于 300 字。 inputs tokenizer(prompt, return_tensorspt).to(DEVICE) input_len inputs.input_ids.shape[1] rounds 10 total_tokens 0 torch.npu.synchronize() start time.time() for i in range(rounds): with torch.no_grad(): out model.generate(**inputs, max_new_tokens256, do_sampleFalse) torch.npu.synchronize() total_tokens out.shape[1] - input_len end time.time() peak torch.npu.max_memory_allocated() / 1024**3 print(fRounds: {rounds}) print(fTotal new tokens: {total_tokens}) print(fElapsed: {end - start:.2f} s) print(fThroughput: {total_tokens / (end - start):.2f} tokens/s) print(fPeak NPU Memory: {peak:.2f} GB)实测下来单 batch、输入约 30 token、输出 256 token 的情况下10 轮连续推理的吞吐在 40 到 60 tokens/s 之间峰值显存稳定在 14.3GB 左右。这个数字对 64GB 的 Atlas 800T 来说余量很大。如果想探高并发把 batch size 拉到 64、输入长度拉到 1024吞吐能到 700 tokens/s 以上峰值显存约 20GB。再往上拉到 128 就会触发 OOM。所以安全水位建议控制在 batch size 64 到 96 之间留 30% 显存余量应对突发长文本。长时运行还有一个观察点连续跑 30 分钟以上显存占用会不会缓慢爬升。如果爬升明显通常是 KV Cache 没释放干净检查一下是不是每次请求都新建了 tokenizer 或 model 实例。正确做法是全局只加载一次请求之间复用。最后说一个我踩过的坑AtomGit Notebook 的免费额度有时间限制长时间压测前先确认剩余时长别跑到一半实例被回收日志全丢。建议把压测结果实时写到文件里或者用tee同时输出到终端和日志文件。python benchmark_npu.py 21 | tee benchmark_$(date %Y%m%d_%H%M).log这样即使实例断了日志还在。
返回列表