推理精度测试
本章节介绍两个精度测评工具。如何使用opencompass工具开展语言模型的推理精度测试,数据集是ceval_gen、mmlu_gen、math_gen、gsm8k_gen、humaneval_gen;以及使用lm-eval工具开展语言模型的推理精度测试,数据集包含mmlu、ARC_Challenge、GSM_8k、Hellaswag、Winogrande、TruthfulQA等,该工具为离线测评,不需要启动推理服务,目前支持大语言模型。
约束限制
- 确保容器可以访问公网。
- 使用opencompass工具需用vllm接口启动在线服务。
- 当前的精度测试仅适用于语言模型精度验证,不适用于多模态模型的精度验证。多模态模型的精度验证,建议使用开源MME数据集和工具(GitHub - BradyFU/Awesome-Multimodal-Large-Language-Models at Evaluation)。
- 配置需要使用的NPU卡,例如:实际使用的是第1张和第2张卡,此处填写为“0,1”,以此类推。
export ASCEND_RT_VISIBLE_DEVICES=0,1
使用Opencompass精度测评工具
- 获取精度测试代码。精度测试代码存放在代码包AscendCloud-LLM的llm_tools/llm_evaluation目录中,代码目录结构如下。目前使用的opencompass版本是0.2.6
benchmark_eval ├──opencompass.sh #运行opencompass脚本 ├──install.sh #安装opencompass脚本 ├──vllm_api.py #启动vllm api服务器 ├──vllm.py #构造vllm评测配置脚本名字 ├──vllm_ppl.py #ppl精度测试脚本
- 精度评测切换conda环境,确保之前启动服务为vllm接口,进入到benchmark_eval目录下,执行如下命令。
conda activate python-3.9.10 bash install.sh
- 在/home/ma-user/AscendCloud/AscendCloud-LLM/llm_tools/llm_evaluation/benchmark_eval目录下安装依赖。
cd opencompass #在benchmark_eval目录下 pip install -e . #下载对应依赖 cd ../human-eval #在benchmark_eval目录下 (可选,如果选择使用humaneval数据集) pip install -e . # 可选,如果选择使用humaneval数据集 pip install huggingface-hub==0.25.1
- (可选)如果需要在humaneval数据集上评估模型代码能力,请执行此步骤,否则忽略这一步。原因是通过opencompass使用humaneval数据集时,需要执行模型生成的代码。请仔细阅读human_eval/execution.py文件第48-57行的注释,内容参考如下。了解执行模型生成代码可能存在的风险,如果接受这些风险,请取消第58行的注释,执行下面步骤5进行评测。
# WARNING # This program exists to execute untrusted model-generated code. Although # it is highly unlikely that model-generated code will do something overtly # malicious in response to this test suite, model-generated code may act # destructively due to a lack of model capability or alignment. # Users are strongly encouraged to sandbox this evaluation suite so that it # does not perform destructive actions on their host or network. For more # information on how OpenAI sandboxes its code, see the accompanying paper. # Once you have read this disclaimer and taken appropriate precautions, # uncomment the following line and proceed at your own risk: # exec(check_program, exec_globals) #第58行
- 执行精度测试启动脚本opencompass.sh,具体操作命令如下,可以根据参数说明修改参数。请确保${work_dir} 已经通过export设置。
vllm_path=${vllm_path} \ host=$host \ service_port=${service_port} \ max_out_len=${max_out_len} \ batch_size=${batch_size} \ eval_datasets=${eval_datasets} \ model_name=${model_name} \ benchmark_type=${benchmark_type} \ bash -x opencompass.sh
参数说明:
- vllm_path:构造vllm评测配置脚本名字,默认为vllm。
- host:与起服务的host保持一致,比如起服务为0.0.0.0,host设置也为0.0.0.0。
- service_port:服务端口,与启动服务时的端口保持,比如8080。
- max_out_len:在运行类似mmlu、ceval等判别式回答时,max_out_len建议设置小一些,比如16。在运行human_eval等生成式回答(生成式回答是对整体进行评测,少一个字符就可能会导致判断错误)时,max_out_len设置建议长一些,比如512,至少包含第一个回答的全部字段。
- batch_size:输入的batch_size大小,不影响精度,只影响得到结果速度。
- eval_datasets:评测数据集和评测方法,比如ceval_gen、mmlu_gen,不同数据集可以详见opencompass下面data目录。
- model_name:评测模型名称,不需要与启动服务时的模型参数保持一致。
- benchmark_type:作为一个保存log结果中的一个变量名,默认选eval。
参考命令:vllm_path=vllm host=0.0.0.0 service_port=8080 max_out_len=16 batch_size=2 eval_datasets=mmlu_gen model_name=llama_7b benchmark_type=eval bash -x opencompass.sh
- (可选)如果同时运行多个数据集,需要将不同数据集通过空格分开,加入到eval_datasets中,比如eval_datasets=ceval_gen mmlu_gen。运行命令如下所示。
cd opencompass python run.py --models vllm --datasets mmlu_gen ceval_gen --debug -w ${output_path}
output_path: 要保存的结果路径。
- (可选)创建新conda环境,安装vllm和opencompass。执行完之后,在 opencompass/configs/models/vllm/vllm_ppl.py 里是ppl的配置项。由于离线执行推理,消耗的显存相当庞大。其中以下参数需要根据实际来调整。
- batch_size,推理时传入的prompts数量,可配合后面的参数适当减少
- offline,是否启动离线模型,使用ppl时必须为True
- tp_size,使用推理的卡数
- max_seq_len,推理的上下文长度,和消耗的显存直接相关,建议稍微高于prompts。其中,mmlu和ceval 建议 3200
另外,在 opencompass/opencompass/models/vllm_api.py 中,可以适当调整 gpu_memory_utilization。如果还是 oom,建议适当往下调整。
最后,如果执行报错提示oom,建议修改数据集的shot配置。例如mmlu,可以修改文件 opencompass/configs/datasets/mmlu/mmlu_ppl_ac766d.py 中的
fix_id_list, 将最大值适当调低。
ppl困惑度评测一般用于base权重测评,会将n个选项上拼接上下文,形成n个序列,再计算着n个序列的困惑度(perplexity)。其中,perplexity最小的序列所对应的选项即为这道题的推理结果。运行时间比较长,例如llama3_8b 跑完mmlu要2~3小时。
在npu卡上,使用多卡进行推理时,需要预置变量
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:False
执行脚本如下:
python run.py --models vllm_ppl --datasets mmlu_ppl -w ${output_path}
output_path 指定保存结果的路径。
参考模型llama3系列模型,数据集mmlu为例,配置如下:
表1 参数配置 模型
max_seq_len
batch_size
shot数
llama3_8b
3200
8
采用默认值
llama3_70b
3200
4
[0, 1, 2]
- (可选) opencompass也支持通过本地权重来进行ppl精度测试。本质上使用transformers进行推理,因为没有框架的优化,执行时间最长。另一方面,由于是使用transformers推理,结果也是最稳定的。对单卡运行的模型比较友好,算力利用率比较高。对多卡运行的推理,缺少负载均衡,利用率低。
在昇腾卡上执行时,需要在 opencompass/opencompass/runners/local.py 中添加如下代码
import torch import torch_npu from torch_npu.contrib import transfer_to_npu
执行脚本如下# for llama3_8b python run.py --datasets mmlu_ppl \ --hf-type base --hf-path {hf-path} \ --max-seq-len 3200 --max-out-len 16 --hf-num-gpus 1 --batch-size 4 \ -w {output_path} --debug
参数说明如下:
- --datasets:评测的数据集及评测方法,其中 mmlu 是数据集,ppl 是评测方法。
- --hf-type:HuggingFace模型权重类型(base,chat),默认为chat,依据实际的模型选择。
- --hf-path:本地 HuggingFace 权重的路径,比如/home/ma-user/nfs/model/Meta-Llama-3-8B。
- --max-seq-len:模型的最大序列长度。
- --max-out-len:模型的最大输出长度。
- --hf-num-gpus:需要使用的卡数。
- --batch-size:推理每次处理的输入数目。
- -w:存放输出结果的目录。
- 查看精度测试结果。
默认情况下,评测结果会按照result/{model_name}/的目录结果保存到对应的测试工程。执行多少次,则会在{model_name}下生成多少次结果。benchmark_eval下生成的log中记录了客户端产生结果。数据集的打分结果在result/{model_name}/...目录下,查找到summmary目录,有txt和csv两种保存格式。
总体打分结果参考txt和csv文件的最后一行,举例如下:
npu:
mmlu:46.6
gpu:
mmlu:47
NPU打分结果(mmlu取值46.6)和GPU打分结果(mmlu取值47)进行对比,误差在1以内(计算公式:(47-46.6) < 1)认为NPU精度和GPU对齐。NPU和GPU的评分结果和社区的评分不能差太远(小于10)认为分数有效。
使用Lm-eval精度测评工具
使用lm-eval工具暂不支持qwen-7b、qwen-14b、qwen-72b、chatglm2-6b、chatglm3-6b模型。
- 精度评测可以在原先conda环境,进入到一个固定目录下,执行如下命令。
rm -rf lm-evaluation-harness/ git clone https://github.com/EleutherAI/lm-evaluation-harness.git cd lm-evaluation-harness git checkout 383bbd54bc621086e05aa1b030d8d4d5635b25e6 pip install -e . pip install aiohttp==3.9.3
- 执行如下精度测试命令,可以根据参数说明修改参数。
lm_eval --model vllm --model_args pretrained=${vllm_path},dtype=auto,tensor_parallel_size=${tensor_parallel_size},gpu_memory_utilization=${gpu_memory_utilization},add_bos_token=True,max_model_len=${max_model_len},quantization=${quantization},distributed_executor_backend='ray' \ --tasks ${task} --batch_size ${batch_size} --log_samples --cache_requests true --trust_remote_code --output_path ${output_path}
参数说明:- model_args:标志向模型构造函数提供额外参数,比如指定运行模型的数据类型;
- vllm_path是模型权重路径;
- max_model_len 是最大模型长度,默认设置为4096;
- gpu_memory_utilization是gpu利用率,如果模型出现oom报错,调小参数;
- tensor_parallel_size是使用的卡数;
- quantization是量化参数,使用非量化权重,去掉quantization参数;如果使用awq、smoothquant或者gptq加载的量化权重,根据量化方式选择对应参数,可选awq,smoothquant,gptq。
- distributed_executor_backend是开启多进程服务方式,选择ray开启。
- model:模型启动模式,可选vllm,openai或hf,hf代表huggingface。
- tasks:评测数据集任务,比如openllm。
- batch_size:输入的batch_size大小,不影响精度,只影响得到结果速度,默认使用auto,代表自动选择batch大小。
- output_path:结果保存路径。
使用lm-eval,比如加载非量化或者awq量化,llama3.2-1b模型的权重,参考命令:lm_eval --model vllm --model_args pretrained="/data/nfs/benchmark/tokenizer/Llama-3.2-1B-Instruct/",dtype=auto,tensor_parallel_size=1,gpu_memory_utilization=0.7,add_bos_token=True,max_model_len=4096,distributed_executor_backend='ray' \ --tasks openllm --batch_size auto --log_samples --cache_requests true --trust_remote_code --output_path ./
使用lm-eval,比如smoothquant量化,llama3.1-70b模型的权重,参考命令:lm_eval --model vllm --model_args pretrained="/data/nfs/benchmark/tokenizer_w8a8/llama3.1-70b/",dtype=auto,tensor_parallel_size=4,gpu_memory_utilization=0.7,add_bos_token=True,max_model_len=4096,quantization="smoothquant",distributed_executor_backend='ray' \ --tasks openllm --batch_size auto --log_samples --cache_requests true --trust_remote_code --output_path ./
- model_args:标志向模型构造函数提供额外参数,比如指定运行模型的数据类型;