opencompass
OpenCompass 是开源大模型评测框架。本文用原生 Hugging Face 封装和 torch_npu,在单卡 910B 上对 Qwen2-0.5B-Instruct 跑 demo_gsm8k_chat_gen(64 条样本)。
备注
阅读本文前,请先按 快速安装昇腾环境 准备好 CANN 与驱动。
前置条件
硬件
Atlas 800T / 900 A2 训练系列(Ascend 910B)。本文示例为单卡。
软件
类别 |
要求 |
|---|---|
CANN |
toolkit + 驱动固件已安装并可 |
Python |
3.12 |
PyTorch |
|
OpenCompass |
从 GitHub 克隆 Release(撰写时 |
模型 |
|
数据 |
GSM8K 的 |
配套机器:Atlas 900 A2 PODc(Ascend 910B4)。配套镜像:swr.cn-south-1.myhuaweicloud.com/ascendhub/cann:9.1.0-910b-ubuntu22.04-py3.12。
本文覆盖原生 Hugging Face + torch_npu,不覆盖 MindIE、LMDeploy 或 vLLM-Ascend。
1. 加载 CANN 环境
新开终端后 CANN 变量不会自动生效。常见容器里 npu-smi 在 /usr/local/sbin,需要把该目录加入 PATH。
source /usr/local/Ascend/ascend-toolkit/set_env.sh
export PATH=/usr/local/sbin:$PATH
export PYTHONNOUSERSITE=1
PYTHONNOUSERSITE=1 让 Python 忽略用户目录里的包。本机如果曾经 pip install --user 过 CANN 相关包,不设这个变量时,pip 解析器可能被带偏。
2. 检查环境是否就绪
2.1 确认 NPU 在线
npu-smi info
命令退出码应为 0,并打印设备列表。表格中的功耗、HBM 占用每次不同,不必与任何样例逐字一致。
备注
若 npu-smi 找不到,回到 快速安装昇腾环境 检查驱动与设备挂载。
2.2 确认工具可用
test -n "$ASCEND_HOME_PATH" && command -v npu-smi >/dev/null && echo cann_ready True
输出结果如下:
cann_ready True
检查 Python 版本:
python --version
输出结果如下:
Python 3.12.xxx
3. 安装 PyTorch NPU 栈
昇腾上的 torch_npu 要从华为 PyPI 额外索引安装,并钉死与 CANN 匹配的版本。numpy 和 pyyaml 也要一起装:torch_npu 的 wheel 没有声明这两项依赖,缺了会在 import torch_npu 之前就失败。
python -m pip install --extra-index-url https://repo.huaweicloud.com/ascend/repos/pypi \
torch==2.9.0 torch_npu==2.9.0.post2 'numpy>=1.23.4,<2' pyyaml
python -c "import numpy, yaml, torch, torch_npu; print('torch', torch.__version__); print('torch_npu', torch_npu.__version__); print('npu_available', torch.npu.is_available())"
输出结果如下:
...
torch 2.9.0...
torch_npu 2.9.0.post2
npu_available True
npu_available 必须是 True。False 时不要继续,先查 CANN、驱动和可见设备。
4. 安装 OpenCompass
源码装到 $HOME/opencompass-qs,将 <ref> 换成目标 Release tag(撰写时最新为 0.5.4)。--no-deps 之后按过滤后的 runtime.txt 装依赖,并跳过 torch 与 GitHub master 上的 rouge_chinese。
mkdir -p "$HOME/opencompass-qs"
cd "$HOME/opencompass-qs"
if [ ! -d opencompass/.git ]; then
GIT_TERMINAL_PROMPT=0
for _ in 1 2 3; do
git clone --depth 1 --branch <ref> \
https://github.com/open-compass/opencompass.git opencompass && break
rm -rf opencompass
sleep 5
done
fi
test -d opencompass/.git
cd opencompass
python -m pip install -e . --no-deps
grep -vE '^[[:space:]]*(#|$)|^torch|rouge_chinese' requirements/runtime.txt \
> "$HOME/opencompass-qs/runtime-local.txt"
python -m pip install \
torch==2.9.0 \
'transformers>=4.37.0,<5' \
'datasets>=3.0.0,<4.0.0' \
'numpy>=1.23.4,<2.0.0' \
'pandas>=2.0,<3' \
huggingface_hub \
rouge-chinese \
-r "$HOME/opencompass-qs/runtime-local.txt"
python -c "import torch, torch_npu, opencompass; print('torch', torch.__version__); print('opencompass', opencompass.__version__); print('npu_available', torch.npu.is_available())"
输出结果如下:
...
torch 2.9.0...
opencompass <ref>
npu_available True
npu_available 仍必须是 True。若 torch 不再以 2.9.0 开头,说明后面的包把 NPU 栈换掉了,卸掉后按第 3–4 节重装。
5. 准备模型和数据
权重从 Hugging Face 拉取。下面打印的本地路径供第 6 节配置使用。
python -c "from huggingface_hub import snapshot_download; print(snapshot_download('Qwen/Qwen2-0.5B-Instruct'))" | tail -n 1
确认权重目录完整:
test -f "<model_path>/config.json" && echo has_config True
输出结果如下:
has_config True
GSM8K 从 openai/grade-school-math 取官方 jsonl,放到源码树的 data/gsm8k/。OpenCompass 默认读这个相对路径。
mkdir -p "$HOME/opencompass-qs/opencompass/data/gsm8k"
cd "$HOME/opencompass-qs/opencompass/data/gsm8k"
if [ ! -f test.jsonl ]; then
curl -fL --retry 3 --retry-delay 5 --connect-timeout 30 \
-o test.jsonl \
https://raw.githubusercontent.com/openai/grade-school-math/master/grade_school_math/data/test.jsonl
fi
if [ ! -f train.jsonl ]; then
curl -fL --retry 3 --retry-delay 5 --connect-timeout 30 \
-o train.jsonl \
https://raw.githubusercontent.com/openai/grade-school-math/master/grade_school_math/data/train.jsonl
fi
test -s test.jsonl && test -s train.jsonl && echo gsm8k_ready True
输出结果如下:
gsm8k_ready True
6. 在 NPU 上评测
下面两份文件放在源码根目录 $HOME/opencompass-qs/opencompass。模型子类在生成前打印设备;评测配置把生成长度压到 32。
保存为 npu_chat.py:
from opencompass.models.huggingface_above_v4_33 import HuggingFacewithChatTemplate
from opencompass.registry import MODELS
@MODELS.register_module()
class HuggingFaceNPUChat(HuggingFacewithChatTemplate):
def generate(self, inputs, max_out_len, **kwargs):
print('\nopencompass_model_device', next(self.model.parameters()).device, flush=True)
return super().generate(inputs, max_out_len, **kwargs)
<model_path> 换成上一节 snapshot_download 打印的路径。保存为 eval_qwen2_gsm8k.py:
from mmengine.config import read_base
from npu_chat import HuggingFaceNPUChat
with read_base():
from opencompass.configs.datasets.demo.demo_gsm8k_chat_gen import gsm8k_datasets
gsm8k_datasets[0]['infer_cfg']['inferencer']['max_out_len'] = 32
datasets = gsm8k_datasets
models = [
dict(
type=HuggingFaceNPUChat,
abbr='qwen2-0.5b-instruct',
path=r'<model_path>',
max_out_len=32,
batch_size=4,
model_kwargs=dict(torch_dtype='bfloat16'),
run_cfg=dict(num_gpus=1),
)
]
--debug 让调度器在当前进程里跑,日志直接出现在终端。
cd "$HOME/opencompass-qs/opencompass"
export PYTHONPATH="$PWD${PYTHONPATH:+:$PYTHONPATH}"
opencompass eval_qwen2_gsm8k.py --debug -w "$HOME/opencompass-qs/work" 2>&1
echo '--- summary ---'
cat "$HOME/opencompass-qs/work"/*/summary/summary_*.txt
输出结果如下:
...
opencompass_model_device npu:0
...
tabulate format
...
demo_gsm8k ... accuracy ... gen ...
...
opencompass_model_device 必须是 npu:0。若打印 cpu,这次生成没有上 NPU,退出码 0 也不能当成功。
原生 HuggingFacewithChatTemplate 在 mmengine.device.is_npu_available() 为真时会把 device_map 设为 npu。