推理精度测试
本章节介绍如何进行推理精度测试,数据集是ceval_gen、mmlu_gen、math_gen、gsm8k_gen、humaneval_gen。
前提条件
确保容器可以访问公网。
Step1 配置精度测试环境
- 获取精度测试代码。精度测试代码存放在代码包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精度测试脚本
- 执行如下命令进入容器。
kubectl exec -it {pod_name} bash
${pod_name}:pod名,例如图1${pod_name}为yourapp-87d9b5b46-c46bk。
- 精度评测切换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数据集
- (可选)如果需要在humaneval数据集上评估模型代码能力,请执行此步骤,否则忽略这一步。原因是通过opencompass使用humaneval数据集时,需要执行模型生成的代码。请仔细阅读human_eval/execution.py文件第48-57行的注释,内容参考如下。了解执行模型生成代码可能存在的风险,如果接受这些风险,请取消第58行的注释,执行下面步骤进行评测。
# 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:存放输出结果的目录。
Step2 查看精度测试结果
默认情况下,评测结果会按照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)/47*100=0.85%)认为NPU精度和GPU对齐。