目錄

  • 在昇騰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模型:一次完整的性能測試與實戰通關指南

NPU升騰模型部署性能測試_ci

引言:從“為什麼選擇昇騰”開始

面對動輒數萬的NVIDIA高端GPU,許多開發者和團隊在部署大模型時都感到“錢包一緊”。當我在為Llama 2-7B尋找一個高性價比的部署方案時,華為昇騰(Ascend)NPU走進了我的視野。其自主可控的達芬奇架構、日益完善的軟件開源生態(昇騰開源倉庫)以及雲上可得的測試資源,構成了我選擇它的三大理由。

本文就將記錄我使用GitCode平台的免費昇騰Notebook實例,完成從環境配置、模型部署到性能測試與優化的全過程。這是一份真實的“踩坑”與“通關”記錄,希望能為後續的探索者點亮一盞燈。

第一幕:環境搭建——好的開始是成功的一半

NPU升騰模型部署性能測試_ci_02

本以為在雲平台創建環境是 simplest thing,沒想到第一個“坑”來得如此之快。

1.1 GitCode Notebook 創建“避坑指南”

NPU升騰模型部署性能測試_性能測試_03

在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的終端中,依次執行以下命令:

NPU升騰模型部署性能測試_性能測試_04

# 檢查系統與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
説明正常可用

NPU升騰模型部署性能測試_Code_05

NPU升騰模型部署性能測試_Code_06

第一個常見的“坑”:直接運行 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} 秒")

NPU升騰模型部署性能測試_ci_07

關鍵點總結:

  1. 在GitCode的昇騰環境中,直接訪問HuggingFace經常會超時,所以推薦使用國內鏡像https://hf-mirror.com
  2. import torch_npu 必須在任何NPU操作之前。
  3. 模型使用 model.to('npu:0') 遷移。
  4. 輸入數據(字典)使用 .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)

NPU升騰模型部署性能測試_性能測試_08

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)提供了寶貴的資源和支持。
  • 給後來者的建議:
  1. 先從雲開始:利用GitCode或ModelArts的免費/低成本資源驗證方案,再決定是否投入硬件。
  2. 仔細閲讀文檔:關注昇騰官方文檔,特別是版本匹配問題。
  3. 擁抱社區:遇到問題時,在昇騰社區或GitCode的Issue中搜索,很可能已有解決方案。

本次部署測試證明了基於昇騰NPU部署和運行Llama 2大模型是一條完全可行的技術路徑。雖然絕對性能並非頂尖,但其在成本、自主可控和穩定性方面的優勢,使其在AI算力多元化的今天,成為一個不容忽視的選擇。


附:GitCode Issue 實踐

根據在模型部署過程中遇到的“輸入張量遷移”典型問題,我已在昇騰ModelZoo-PyTorch倉庫提交了詳細的Issue,包含問題分析、解決步驟與代碼示例。