跳到主要内容
昇腾 NPU 部署 Llama 大模型实战指南与常见问题解决 | 极客日志
Python AI 算法
昇腾 NPU 部署 Llama 大模型实战指南与常见问题解决 综述由AI生成 在昇腾 NPU 上部署 Llama-2-7B 大模型的完整流程。涵盖环境准备(GitCode Notebook)、依赖安装、模型下载及运行测试。详细记录了 torch_npu 导入、设备映射、权限访问等常见错误及其解决方案。性能测试显示吞吐量约为 16-17 tokens/s,并提供了 MindSpeed-LLM、INT8 量化及批处理推理等优化建议。
路由之心 发布于 2026/4/6 更新于 2026/5/23 35 浏览昇腾 NPU 部署 Llama 大模型实战指南
选择昇腾 NPU 的原因
本文分享了在昇腾 NPU 上部署测试 Llama-2-7B 大模型的全过程。提供踩坑经验。作者因其他硬件价格高、服务器昂贵,选择昇腾 NPU,其自主可控的达芬奇架构、完善的开源生态及 GitCode 免费测试资源是主要吸引力。
一、为什么选择昇腾?
以前我也觉得'非 NVIDIA 不用',直到研究国产 AI 芯片才发现,昇腾居然藏着这么多优点:
自主可控 :昇腾用的是华为自研的达芬奇架构,不用怕突然断供,搞项目时心里踏实多了。
生态完善 :去昇腾 GitCode 仓库(https://gitcode.com/ascend )一看,30 多个开源项目摆得整整齐齐,PyTorch、TensorFlow 都能适配,连 MindSpeed-LLM 这种专门的大模型框架都有。
成本效益 :没硬件没关系,GitCode 能申请免费的昇腾 Notebook 实例,虽然是限时的,但用来测试模型完全够了。花几十块在 ModelArts 按小时付费也行,比买硬件划算。
二、环境准备:GitCode 实例配置
1. 为什么选云上测试?
实话说,随便一个服务器几万甚至十几万的价格,普通开发者看看就好。华为云 ModelArts 能按小时租昇腾 NPU 环境,不过 GitCode 的免费资源更香,零成本先把流程跑通。
2. 创建 Notebook 实例
进入 GitCode 控制台后,创建过程看着简单,实则暗藏细节,关键配置如下:
计算类型必选 NPU :别手滑选 CPU 或 GPU!我一开始误点 CPU,跑起来很慢,后来才发现是自己犯了低级错误。
规格认准'NPU basic' :选 1*NPU 800T A2、32v CPU、64GB 内存的配置,性能足够跑 Llama-2-7B。
镜像别瞎选 :一定要挑'euler2.9-py38-torch2.1.0-cann8.0-openmind0.6-notebook'这个,预装了 PyTorch 2.1.0、CANN 8.0 这些关键工具。
存储选免费 50G :模型文件也就 13GB 左右,50G 完全够用。创建后等一分钟左右,实例就启动了,接下来就能进入 Jupyter Notebook 界面操作啦。
3. 环境配置
PyTorch 2.1.0:版本够新,兼容性也不错;
CANN 8.0:昇腾的核心计算架构,跑模型全靠它;
Python 3.8:不用自己装环境,直接用就行;
torch_npu 2.1.0:PyTorch 适配昇腾的关键插件,后面会用到。
三、验证环境 刚进 Notebook,我就迫不及待想验证 NPU 能不能用,结果第一个坑就找上门了。
1. 打开 Terminal 在 Notebook 界面找到'终端'入口,点开就是熟悉的 Linux 命令行。
2. 验证 NPU
cat /etc/os-release
NAME="openEuler"
VERSION="22.03 (LTS-SP3)"
ID="openEuler"
VERSION_ID="22.03"
PRETTY_NAME="openEuler 22.03 (LTS-SP3)"
ANSI_COLOR="0;31"
python3 --version
Python 3.8.19
python -c "import torch; print(f'PyTorch 版本:{torch.__version__}')"
PyTorch 版本:2.1.0
python -c "import torch_npu; print(f'torch_npu 版本:{torch_npu.__version__}')"
torch_npu 版本:2.1.0.post3
接着我想验证 NPU 是否可用,直接跑了 python -c "import torch; print(torch.npu.is_available())",结果报错 AttributeError: module 'torch' has no attribute 'npu',当时我还以为环境没装好,折腾了半天才发现——必须先导入 torch_npu 插件 !正确的命令应该是这样:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
python -c "import torch; import torch_npu; print(torch.npu.is_available())"
看到'True'的时候,我才算松了口气,确认 NPU 能正常用了,而且有 1 个 NPU 设备。后来才发现,这个细节文档里没明说,纯纯是自己踩坑踩出来的经验。
四、安装依赖 环境验证完,以为能直接跑模型了?别着急,还有个关键依赖没装——transformers 库。虽然镜像里有 PyTorch 和 torch_npu,但跑 Llama 大模型必须用这个库,得手动装一下。
pip install transformers accelerate -i https://pypi.tuna.tsinghua.edu.cn/simple
我当时用了清华源,一会就装好了,要是用默认源,说不定还得等半天,大家记得加上镜像地址,省时间!
五、部署 Llama 终于到了最关键的部署环节,本以为能顺顺利利,结果又踩了好几个坑,还好最后都解决了。
1. 模型下载 一开始我想从 Llama-2 官方仓库 meta-llama/Llama-2-7b-hf 下载,结果发现要申请访问权限,而且国内访问 HuggingFace 经常超时,下载到一半就卡住。
后来才找到解决方案:用开源社区的镜像版本 NousResearch/Llama-2-7b-hf,不用申请权限,下载还稳定,几分钟就搞定了。
2. 创建测试脚本 我本来想在 Terminal 里用 vim 创建脚本,结果报错 sh: vim: command not found,原来 GitCode 环境里没装 vim。其实不用纠结,直接在 Notebook 里新建 Python 文件就行。
export HF_ENDPOINT=https://hf-mirror.com
3. 核心代码 代码不算复杂,但有两个地方特别容易出错,我都标出来了:
import torch
import torch_npu
from transformers import AutoModelForCausalLM, AutoTokenizer
import time
print ("开始测试..." )
MODEL_NAME = "NousResearch/Llama-2-7b-hf"
print (f"下载模型:{MODEL_NAME} " )
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
torch_dtype=torch.float16,
low_cpu_mem_usage=True
)
print ("加载到 NPU..." )
model = model.npu()
model.eval ()
print (f"显存占用:{torch.npu.memory_allocated()/1e9 :.2 f} GB" )
prompt = "The capital of France is"
inputs = tokenizer(prompt, return_tensors="pt" )
inputs = {k: v.npu() for k, v in inputs.items()}
start = time.time()
outputs = model.generate(**inputs, max_new_tokens=50 )
end = time.time()
text = tokenizer.decode(outputs[0 ])
print (f"\n生成文本:{text} " )
print (f"耗时:{(end-start)*1000 :.2 f} ms" )
print (f"吞吐量:{50 /(end-start):.2 f} tokens/s" )
还有个坑要注意:代码里不能写 inputs.npu(),得用 inputs.to('npu:0'),我一开始写错了,报错后才改对,大家别犯同样的错:
inputs = tokenizer(prompt, return_tensors="pt" ).to('npu:0' )
4. 模型下载过程 模型文件总共约 13GB,分成了两个 shard 文件:model-00001-of-00002.safetensors 和 model-00002-of-00002.safetensors。我当时用镜像版本下载,速度还不错,大概 5 分钟就下完了。加载完成后看了下显存,占用 13.61GB,和 7B 模型在 FP16 精度下的理论大小(约 14GB)差不多,很正常。
六、性能测试 搞定模型下载后,我兴冲冲想测测昇腾 NPU 的实力,结果写测试脚本时又闹了不少笑话 —— 一开始把计时放在 model.generate() 外面,算出的速度快得离谱,还以为昇腾突然'开了挂',后来才发现是没算预热时间,纯属自欺欺人。
6.1 性能测试 第一次的测试脚本报错,这里就不贴出来了,见下面修改后的完整脚本。
Traceback (most recent call last):
File "test_llama.py" , line 47 , in <module >
result = benchmark (case ["输入" ], max_new_tokens=100 if case ["场景" ] != "代码生成" else 150 )
File "test_llama.py" , line 7 , in benchmark
inputs = tokenizer (prompt, return_tensors="pt" ).to ("npu:0" )
NameError: name 'tokenizer' is not defined
然后经历了 NameError 的暴击后,我痛定思痛重构了测试脚本,不仅解决了变量作用域问题,还加了不少实用细节。现在这套代码亲测能跑,再也不用对着屏幕发呆了——
import torch
import torch_npu
import time
import json
from datetime import datetime
from transformers import AutoModelForCausalLM, AutoTokenizer
MODEL_NAME = "NousResearch/Llama-2-7b-hf"
DEVICE = "npu:0"
WARMUP_RUNS = 3
TEST_RUNS = 10
SAVE_RESULT = True
def load_model_and_tokenizer (model_name ):
"""加载模型和 tokenizer 的专用函数,避免重复代码"""
print (f"正在加载模型 {model_name} ..." )
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.float16,
low_cpu_mem_usage=True
).to(DEVICE)
model.eval ()
print (f"模型已加载到{DEVICE} ,显存占用:{torch.npu.memory_allocated()/1e9 :.2 f} GB" )
return model, tokenizer
def benchmark (prompt, tokenizer, model, max_new_tokens=100 ):
"""性能测试核心函数,带预热和同步"""
inputs = tokenizer(prompt, return_tensors="pt" ).to(DEVICE)
print (f"预热中...({WARMUP_RUNS} 次)" )
for _ in range (WARMUP_RUNS):
with torch.no_grad():
_ = model.generate(**inputs, max_new_tokens=max_new_tokens, do_sample=False , pad_token_id=tokenizer.eos_token_id)
print (f"开始测试...({TEST_RUNS} 次)" )
latencies = []
for i in range (TEST_RUNS):
torch.npu.synchronize()
start_time = time.time()
with torch.no_grad():
outputs = model.generate(**inputs, max_new_tokens=max_new_tokens, do_sample=False , pad_token_id=tokenizer.eos_token_id)
torch.npu.synchronize()
end_time = time.time()
latency = end_time - start_time
latencies.append(latency)
print (f"第{i+1 } 次测试:耗时{latency:.2 f} 秒,速度{max_new_tokens/latency:.2 f} tokens/秒" )
avg_latency = sum (latencies)/len (latencies)
throughput = max_new_tokens / avg_latency
return {
"prompt" : prompt,
"max_new_tokens" : max_new_tokens,
"平均延迟 (秒)" : round (avg_latency, 2 ),
"平均吞吐量 (tokens/秒)" : round (throughput, 2 ),
"显存占用 (GB)" : round (torch.npu.memory_allocated()/1e9 , 2 )
}
if __name__ == "__main__" :
model, tokenizer = load_model_and_tokenizer(MODEL_NAME)
test_cases = [
{"场景" : "英文短文本生成" , "输入" : "The capital of France is" , "生成长度" : 100 },
{"场景" : "中文对话" , "输入" : "请解释什么是人工智能:" , "生成长度" : 100 },
{"场景" : "代码生成" , "输入" : "Write a Python function to calculate fibonacci:" , "生成长度" : 150 }
]
results = []
for case in test_cases:
print (f"\n===== 测试场景:{case ['场景' ]} =====" )
result = benchmark(
prompt=case ["输入" ],
tokenizer=tokenizer,
model=model,
max_new_tokens=case ["生成长度" ]
)
result["场景" ] = case ["场景" ]
results.append(result)
print (f"场景结果:{result} " )
if SAVE_RESULT:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S" )
filename = f"llama_benchmark_{timestamp} .json"
with open (filename, "w" , encoding="utf-8" ) as f:
json.dump(results, f, ensure_ascii=False , indent=2 )
print (f"\n测试结果已保存到 {filename} " )
print ("\n===== 测试完成 =====" )
print ("性能总结:" )
for res in results:
print (f"{res['场景' ]} :{res['平均吞吐量 (tokens/秒)' ]} tokens/秒" )
6.2 为啥这套代码靠谱?
变量作用域清清楚楚 :把 tokenizer 和 model 作为参数传给 benchmark 函数,再也不会出现 NameError。
细节拉满的测试逻辑 :
单独的 load_model_and_tokenizer 函数,避免代码重复
强制 torch.npu.synchronize() 同步计时,结果真实可信
加了 model.eval() 和 with torch.no_grad(),显存占用直降 2GB
自动保存 JSON 结果,带时间戳不怕重名
新手友好的提示信息 :运行时会打印每步进度,比如'预热中…(3 次)'、'第 2 次测试:耗时 5.8 秒',就算出问题也能快速定位在哪一步翻车。
6.3 运行效果参考 我在 GitCode 的昇腾实例上跑出来的结果大概是这样(供参考):
性能总结:
英文短文本生成:16.75 tokens/秒
中文对话:16.58 tokens/秒
代码生成:16.59 tokens/秒
虽然不算顶尖速度,但胜在稳定可靠。最关键的是——这套代码真的不会报 NameError 了!
七、常见问题与解决方案 整个过程中,我踩了不少坑,现在整理出来,大家看完就能避开,不用再走弯路:
坑 1:torch.npu 找不到
现象 :运行 torch.npu.is_available() 报错 AttributeError: module 'torch' has no attribute 'npu'。
原因 :torch_npu 是单独的插件,不是 PyTorch 自带的,必须显式导入。
解决 :在代码开头加一行 import torch_npu,顺序在 import torch 之后就行。
坑 2:tokenizer.npu() 不存在
现象 :写 inputs = tokenizer(...).npu() 报错,说没有 npu() 方法。
原因 :tokenizer 返回的是字典类型,字典没有 npu() 这个方法,和 Tensor 不一样。
解决 :换成 inputs = tokenizer(...).to('npu:0'),用 to() 方法指定设备就行。
坑 3:Llama 下载需要权限
现象 :访问 meta-llama/Llama-2-7b-hf 被拒绝,提示要申请权限。
原因 :官方仓库有访问限制,不是所有人都能直接下载。
解决 :用开源镜像版本 NousResearch/Llama-2-7b-hf,不用申请权限,下载还快。
坑 4:网络超时
现象 :下载模型到一半卡住,提示 timeout。
原因 :国内访问 HuggingFace 不稳定,容易断连。
解决 :要么用国内镜像加速(执行 export HF_ENDPOINT=https://hf-mirror.com),要么用 ModelScope 下载(from modelscope import snapshot_download; model_dir = snapshot_download('shakechen/Llama-2-7b-hf')),两种方法都能解决超时问题。
八、性能优化建议 虽然这次测试的吞吐量不算高,但也不是没办法优化,我总结了三个方向,大家可以试试:
1. 用 mindie 框架 这是昇腾官方出的大模型框架,专门针对昇腾 NPU 做了深度优化,比用原生 transformers 代码快不少,我后面打算试试这个。
2. 试试 INT8 量化 用 INT8 精度加载模型,既能减少显存占用,还能提升速度。代码也不难改,加个量化配置就行:
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_8bit=True )
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
quantization_config=quantization_config
)
理论上能快 20%-30%,显存占用也能降一半,值得尝试。
3. 批处理推理 如果有多个请求,别一个一个处理,用 batch 推理能显著提升吞吐量。比如一次处理 4 个请求:
prompts = ["prompt1" , "prompt2" , "prompt3" , "prompt4" ]
inputs = tokenizer(prompts, return_tensors="pt" , padding=True ).to('npu:0' )
outputs = model.generate(**inputs, max_new_tokens=100 )
我这次只测了 batch=1,要是 batch 调大,吞吐量肯定能上去。
九、总结与建议 折腾了这么久,我对昇腾 NPU 也算有了直观的认识,总结几点感受和建议,给想尝试的朋友参考:
技术层面 :部署流程不算复杂,PyTorch 代码改一改就能用,文档和生态比我预期的完善,就是有些细节要注意(比如导入 torch_npu)。
适用场景 :适合对供应链自主可控有要求的政企项目,预算有限但想跑大模型的团队,还有离线批量推理任务;要是做实时交互式应用,可能需要再优化优化性能。
成本效益 :云上测试几十块就能验证方案,硬件采购也比 NVIDIA GPU 便宜,综合性价比还不错。
先云上测试,别盲目买硬件 :先在 ModelArts 花几十块试试,或者 GitCode 免费薅个实例,跑通流程再决定要不要买硬件,避免浪费钱。
镜像别乱选,认准 NPU+PyTorch :选错镜像会多走很多弯路,就用我前面推荐的那个,省得自己装环境。
细节别忽略 :import torch_npu 必须加,to('npu:0') 别写成 .npu(),这些小细节错了就会报错。
合理预期性能 :别指望昇腾能比顶级 NVIDIA GPU 快,但满足日常需求没问题,关键是性价比和自主可控。
多逛社区 :GitCode 上有很多实际案例,遇到问题先搜一搜,说不定别人早就踩过同样的坑了。
这次测试虽然踩了不少坑,但总体来说很值,真正体验了一把国产 AI 芯片的实力。昇腾的生态确实在慢慢变好,虽然性能还有提升空间,但对于很多场景来说已经够用了。如果你也对国产 AI 芯片感兴趣,不妨试试,说不定会有意外收获!
注:本文内容基于昇腾 NPU 环境实测,仅供参考。
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
随机西班牙地址生成器 随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online