目錄
- 在昇騰NPU上跑Llama 2模型:一次完整的性能測試與實戰通關指南
- 引言:從“為什麼選擇昇騰”開始
- 第一幕:環境搭建——好的開始是成功的一半
- 1.1 GitCode Notebook 創建“避坑指南”
- 1.2 環境驗證:“Hello, NPU!”
- 第二幕:模型部署——從下載到運行的“荊棘之路”
- 2.1 安裝依賴與模型下載
- 2.2 核心部署代碼與“坑”的化解
- 第三幕:性能測試——揭開昇騰NPU的真實面紗
- 3.1 嚴謹的性能測試腳本
- 3.2 測試結果與分析
- 第四幕:性能優化——讓Llama跑得更快
- 4.1 使用昇騰原生大模型框架
- 4.2 INT8量化
- 4.3 啓用批處理(Batch Inference)
- 總結與建議
- 附:GitCode Issue 實踐
在昇騰NPU上跑Llama 2模型:一次完整的性能測試與實戰通關指南
引言:從“為什麼選擇昇騰”開始
面對動輒數萬的NVIDIA高端GPU,許多開發者和團隊在部署大模型時都感到“錢包一緊”。當我在為Llama 2-7B尋找一個高性價比的部署方案時,華為昇騰(Ascend)NPU走進了我的視野。其自主可控的達芬奇架構、日益完善的軟件開源生態(昇騰開源倉庫)以及雲上可得的測試資源,構成了我選擇它的三大理由。
本文就將記錄我使用GitCode平台的免費昇騰Notebook實例,完成從環境配置、模型部署到性能測試與優化的全過程。這是一份真實的“踩坑”與“通關”記錄,希望能為後續的探索者點亮一盞燈。
第一幕:環境搭建——好的開始是成功的一半
本以為在雲平台創建環境是 simplest thing,沒想到第一個“坑”來得如此之快。
1.1 GitCode Notebook 創建“避坑指南”
在GitCode創建Notebook實例時,幾個關鍵配置決定了後續的成敗:
- 計算類型:務必選擇 NPU
- 規格選擇:NPU basic
- 鏡像選擇:這是關鍵!必須選擇預裝了CANN、PyTorch適配器等核心工具的鏡像,例如 euler2.9-py38-torch2.1.0-cann8.0-openmind0.6-notebook
1.2 環境驗證:“Hello, NPU!”
實例啓動後,我們首先需要確認NPU可用。在Jupyter Notebook的終端中,依次執行以下命令:
# 檢查系統與Python版本
cat /etc/os-release
python3 --version
# 檢查PyTorch及torch_npu
python -c "import torch; print(f'PyTorch版本: {torch.__version__}')"
python -c "import torch_npu; print(f'torch_npu版本: {torch_npu.__version__}')"
# 沒有的話安裝,先執行pip install --upgrade pip
pip install torch torchvision torchaudio
pip install torch-npu
看到
PyTorch版本: 2.4.0
torch_npu版本: 2.4.0.post4
説明正常可用
第一個常見的“坑”:直接運行 torch.npu.is_available() 會報錯 AttributeError。原因與解決方案:torch_npu 是一個獨立的插件,必須顯式導入後才能註冊NPU後端。正確的驗證方式是:
python -c "import torch; import torch_npu; print(torch.npu.is_available())"
看到 True ,恭喜你,NPU環境準備就緒!
第二幕:模型部署——從下載到運行的“荊棘之路”
環境搞定,接下來就是請“Llama 2”這位大神上場了。
2.1 安裝依賴與模型下載
安裝運行Llama 2所必須的庫,建議使用國內鏡像加速:
pip install transformers accelerate -i https://pypi.tuna.tsinghua.edu.cn/simple
第二個“坑”——模型下載權限與網絡。直接訪問Meta官方的Llama 2倉庫 (meta-llama/Llama-2-7b-hf) 需要申請權限,且國內下載速度堪憂。解決方案:使用社區鏡像版本,如 NousResearch/Llama-2-7b-hf,無需權限,下載穩定。
2.2 核心部署代碼與“坑”的化解
創建一個Python腳本(如 llama_demo.py),以下是核心代碼及注意事項:
import os
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com' #在GitCode的昇騰環境中,直接訪問HuggingFace經常會超時,所以使用國內鏡像
import torch
import torch_npu # 切記!
from transformers import AutoModelForCausalLM, AutoTokenizer
import time
# 配置
MODEL_NAME = "NousResearch/Llama-2-7b-hf"
DEVICE = "npu:0"
print("開始加載模型...")
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
torch_dtype=torch.float16, # 使用FP16節省顯存
low_cpu_mem_usage=True
)
print("將模型移至NPU...")
model = model.to(DEVICE)
model.eval() # 設置為評估模式
# 第三個“坑”:輸入張量遷移
prompt = "The capital of France is"
# 錯誤寫法:inputs = tokenizer(prompt, return_tensors="pt").npu() -> 報錯!
# 正確寫法:
inputs = tokenizer(prompt, return_tensors="pt").to(DEVICE)
# 推理
with torch.no_grad():
start_time = time.time()
outputs = model.generate(**inputs, max_new_tokens=50)
end_time = time.time()
generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(f"生成內容: {generated_text}")
print(f"推理耗時: {end_time - start_time:.2f} 秒")
關鍵點總結:
- 在GitCode的昇騰環境中,直接訪問HuggingFace經常會超時,所以推薦使用國內鏡像https://hf-mirror.com
- import torch_npu 必須在任何NPU操作之前。
- 模型使用 model.to('npu:0') 遷移。
- 輸入數據(字典)使用 .to('npu:0') 遷移,而非不存在的 .npu() 方法。
第三幕:性能測試——揭開昇騰NPU的真實面紗
是騾子是馬,拉出來遛遛。我設計了一個更嚴謹的測試腳本來評估性能。
3.1 嚴謹的性能測試腳本
import os
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com' #在GitCode的昇騰環境中,直接訪問HuggingFace經常會超時,所以使用國內鏡像
import torch
import torch_npu
import time
import json
from transformers import AutoModelForCausalLM, AutoTokenizer
# 配置
MODEL_NAME = "NousResearch/Llama-2-7b-hf"
DEVICE = "npu:0"
WARMUP_RUNS = 3
TEST_RUNS = 5
def load_model():
print("加載模型與分詞器...")
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()
return model, tokenizer
def benchmark(prompt, model, tokenizer, max_new_tokens=100):
inputs = tokenizer(prompt, return_tensors="pt").to(DEVICE)
# 預熱
print("預熱運行...")
for _ in range(WARMUP_RUNS):
with torch.no_grad():
_ = model.generate(**inputs, max_new_tokens=max_new_tokens)
# 正式測試
print("開始性能測試...")
latencies = []
for i in range(TEST_RUNS):
torch.npu.synchronize() # 同步,確保計時準確
start = time.time()
with torch.no_grad():
_ = model.generate(**inputs, max_new_tokens=max_new_tokens)
torch.npu.synchronize()
end = time.time()
latency = end - start
latencies.append(latency)
print(f" 第{i+1}次耗時: {latency:.2f}s")
avg_latency = sum(latencies) / len(latencies)
throughput = max_new_tokens / avg_latency
return throughput, avg_latency
if __name__ == "__main__":
model, tokenizer = load_model()
test_cases = [
{"場景": "英文生成", "提示": "The future of artificial intelligence is", "長度": 100},
{"場景": "中文問答", "提示": "請用簡單的話解釋量子計算:", "長度": 100},
{"場景": "代碼生成", "提示": "Write a Python function to reverse a string:", "長度": 150},
]
print("\n" + "="*50)
print("性能測試結果")
print("="*50)
for case in test_cases:
throughput, avg_latency = benchmark(case["提示"], model, tokenizer, case["長度"])
print(f"- {case['場景']}:")
print(f" 平均延遲: {avg_latency:.2f}s")
print(f" 吞吐量: {throughput:.2f} tokens/s")
print("="*50)
3.2 測試結果與分析
在GitCode的NPU Basic實例上,測試結果大致如下:
|
測試類型
|
第1次耗時
|
第2次耗時
|
第3次耗時
|
第4次耗時
|
第5次耗時
|
平均延遲
|
吞吐量
|
|
英文生成
|
4.87s
|
4.88s
|
4.78s
|
4.96s
|
5.22s
|
4.94s
|
20.24 tokens/s
|
|
中文問答
|
4.84s
|
4.86s
|
5.01s
|
4.81s
|
4.81s
|
4.87s
|
20.55 tokens/s
|
|
代碼生成
|
7.14s
|
7.19s
|
7.32s
|
7.37s
|
7.16s
|
7.24s
|
20.73 tokens/s
|
結果分析:
- 性能表現:吞吐量穩定在 20-30 tokens/秒 左右。這個速度對於離線批處理、內部工具開發和對實時性要求不高的場景是足夠的,但與頂級消費級GPU相比仍有差距。
- 穩定性:在整個測試過程中,昇騰NPU表現出了良好的穩定性,沒有出現崩潰或性能波動。
- 結論:昇騰NPU為運行Llama 2這類大模型提供了一個可行、穩定且具有高性價比(尤其考慮國產化與雲上成本) 的算力選項。
第四幕:性能優化——讓Llama跑得更快
如果對默認性能不滿意,這裏有幾個可以嘗試的優化方向:
4.1 使用昇騰原生大模型框架
昇騰社區提供了專為大模型優化的 MindSpeed-LLM 框架(GitCode鏈接)。該框架對昇騰硬件做了深度優化,通常能獲得比原生PyTorch更好的性能。
4.2 INT8量化
通過量化,可以顯著降低模型顯存佔用並提升推理速度。
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
model = AutoModelForCausalLM.from_pretrained(
MODEL_NAME,
quantization_config=quantization_config,
device_map="auto"
)
4.3 啓用批處理(Batch Inference)
同時處理多個請求可以大幅提升吞吐量。
prompts = ["Prompt 1", "Prompt 2", "Prompt 3", "Prompt 4"]
inputs = tokenizer(prompts, return_tensors="pt", padding=True).to(DEVICE)
outputs = model.generate(**inputs, max_new_tokens=100)
總結與建議
經過這一番從“踩坑”到“通關”的實戰,我對昇騰NPU的總結如下:
- 適用場景:非常適合追求技術自主可控、預算有限、進行離線批處理或構建內部AI工具的團隊和個人開發者。
- 生態體驗:軟件棧(CANN, torch_npu)日趨成熟,開源社區(Ascend GitCode)提供了寶貴的資源和支持。
- 給後來者的建議:
- 先從雲開始:利用GitCode或ModelArts的免費/低成本資源驗證方案,再決定是否投入硬件。
- 仔細閲讀文檔:關注昇騰官方文檔,特別是版本匹配問題。
- 擁抱社區:遇到問題時,在昇騰社區或GitCode的Issue中搜索,很可能已有解決方案。
本次部署測試證明了基於昇騰NPU部署和運行Llama 2大模型是一條完全可行的技術路徑。雖然絕對性能並非頂尖,但其在成本、自主可控和穩定性方面的優勢,使其在AI算力多元化的今天,成為一個不容忽視的選擇。
附:GitCode Issue 實踐
根據在模型部署過程中遇到的“輸入張量遷移”典型問題,我已在昇騰ModelZoo-PyTorch倉庫提交了詳細的Issue,包含問題分析、解決步驟與代碼示例。