OpenCompass/docs/zh_cn/get_started/faq.md
2024-10-31 18:08:09 +08:00

148 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 常见问题
## 通用
### ppl 和 gen 有什么区别和联系?
`ppl` 是困惑度 (perplexity) 的缩写,是一种评价模型进行语言建模能力的指标。在 OpenCompass 的语境下,它一般指一种选择题的做法:给定一个上下文,模型需要从多个备选项中选择一个最合适的。此时,我们会将 n 个选项拼接上上下文后,形成 n 个序列,然后计算模型对这 n 个序列的 perplexity我们认为其中 perplexity 最低的序列所对应的选项即为模型在这道题上面的推理结果,该种评测方法的后处理简单直接、确定性高。
`gen` 是生成 (generate) 的缩写。在 OpenCompass 的语境下,它指的是在给定上下文的情况下,模型往后续写的结果就是这道题目上的推理结果。一般来说,续写得到的字符串需要结合上比较重的后处理过程,才能进行可靠的答案提取,从而完成评测。
从使用上来说,基座模型的单项选择题和部分具有选择题性质的题目会使用 `ppl`,基座模型的不定项选择和非选择题都会使用 `gen`。而对话模型的所有题目都会使用 `gen`,因为许多商用 API 模型不会暴露 `ppl` 的接口。但也存在例外情况,例如我们希望基座模型输出解题思路过程时 (例如 Let's think step by step),我们同样会使用 `gen`,但总体的使用如下图所示:
| | ppl | gen |
| -------- | ----------- | ------------------ |
| 基座模型 | 仅 MCQ 任务 | MCQ 以外的其他任务 |
| 对话模型 | 无 | 所有任务 |
`ppl` 高度类似地,条件对数概率 `clp` (conditional log probability) 是在给定上下文的情况下,计算下一个 token 的概率。它也仅适用于选择题,考察概率的范围仅限于备选项标号所对应的 token取其中概率最高的 token 所对应的选项为模型的推理结果。与 ppl 相比,`clp` 的计算更加高效,仅需要推理一次,而 ppl 需要推理 n 次,但坏处是,`clp` 受制于 tokenizer在例如选项前后有无空格符号时tokenizer 编码的结果会有变化,导致测试结果不可靠。因此 OpenCompass 中很少使用 `clp`
### OpenCompass 如何控制 few shot 评测的 shot 数目?
在数据集配置文件中,有一个 `retriever` 的字段,该字段表示如何召回数据集中的样本作为上下文样例,其中最常用的是 `FixKRetriever` 表示固定使用某 k 个样本,因此即为 k-shot。另外还有 `ZeroRetriever` 表示不使用任何样本,这在大多数情况下意味着 0-shot。
另一方面in context 的样本也可以直接在数据集的模板中指定,在该情况下亦会搭配使用 `ZeroRetriever`,但此时的评测并不是 0-shot而需要根据具体的模板来进行确定。具体请看 [prompt](../prompt/prompt_template.md)
### OpenCompass task 的默认划分逻辑是什么样的?
OpenCompass 默认使用 num_worker_partitioner。OpenCompass 的评测从本质上来说就是有一系列的模型和一系列的数据集然后两两组合用每个模型去跑每个数据集。对于同一个模型OpenCompass 会将其拆分为 `--max-num-workers` (或 config 中的 `infer.runner.max_num_workers`) 个 task为了保证每个 task 的运行耗时均匀,每个 task 均会所有数据集的一部分。示意图如下:
![num_worker_partitioner](https://github.com/open-compass/opencompass/assets/17680578/68c57a57-0804-4865-a0c6-133e1657b9fc)
### OpenCompass 在 slurm 等方式运行时,为什么会有部分 infer log 不存在?
因为 log 的文件名并不是一个数据集的切分,而是一个 task 的名字。由于 partitioner 有可能会将多个较小的任务合并成一个大的,而 task 的名字往往就是第一个数据集的名字。因此该 task 中后面的数据集的名字对应的 log 都不会出现,而是会直接写在第一个数据集对应的 log 中
### OpenCompass 中的断点继续逻辑是什么样的?
只要使用 --reuse / -r 开关,则会进行断点继续。首先 OpenCompass 会按照最新的 config 文件配置模型和数据集,然后在 partitioner 确定分片大小并切片后,对每个分片依次查找,若该分片已完成,则跳过;若该分片未完成或未启动,则加入待测列表。然后将待测列表中的任务依次进行执行。注意,未完成的任务对应的输出文件名一般是 `tmp_xxx`,此时模型会从该文件中标号最大的一个数据开始往后继续跑,直到完成这个分片。
根据上述过程,有如下推论:
- 在已有输出文件夹的基础上断点继续时,不可以更换 partitioner 的切片方式,或者不可以修改 `--max-num-workers` 的入参。(除非使用了 `tools/prediction_merger.py` 工具)
- 如果数据集有了任何修改,不要断点继续,或者根据需要将原有的输出文件进行删除后,全部重跑。
### OpenCompass 如何分配 GPU
OpenCompass 使用称为 task (任务) 的单位处理评估请求。每个任务都是模型和数据集的独立组合。任务所需的 GPU 资源完全由正在评估的模型决定,具体取决于 `num_gpus` 参数。
在评估过程中OpenCompass 部署多个工作器并行执行任务。这些工作器不断尝试获取 GPU 资源直到成功运行任务。因此OpenCompass 始终努力充分利用所有可用的 GPU 资源。
例如,如果您在配备有 8 个 GPU 的本地机器上使用 OpenCompass每个任务要求 4 个 GPU那么默认情况下OpenCompass 会使用所有 8 个 GPU 同时运行 2 个任务。但是,如果您将 `--max-num-workers` 设置为 1那么一次只会处理一个任务只使用 4 个 GPU。
### 我如何控制 OpenCompass 占用的 GPU 数量?
目前,没有直接的方法来指定 OpenCompass 可以使用的 GPU 数量。但以下是一些间接策略:
**如果在本地评估:**
您可以通过设置 `CUDA_VISIBLE_DEVICES` 环境变量来限制 OpenCompass 的 GPU 访问。例如,使用 `CUDA_VISIBLE_DEVICES=0,1,2,3 python run.py ...` 只会向 OpenCompass 暴露前四个 GPU确保它同时使用的 GPU 数量不超过这四个。
**如果使用 Slurm 或 DLC**
尽管 OpenCompass 没有直接访问资源池,但您可以调整 `--max-num-workers` 参数以限制同时提交的评估任务数量。这将间接管理 OpenCompass 使用的 GPU 数量。例如,如果每个任务需要 4 个 GPU您希望分配总共 8 个 GPU那么应将 `--max-num-workers` 设置为 2。
### 找不到 `libGL.so.1`
opencv-python 依赖一些动态库,但环境中没有,最简单的解决办法是卸载 opencv-python 再安装 opencv-python-headless。
```bash
pip uninstall opencv-python
pip install opencv-python-headless
```
也可以根据报错提示安装对应的依赖库
```bash
sudo apt-get update
sudo apt-get install -y libgl1 libglib2.0-0
```
### 运行报错 Error: mkl-service + Intel(R) MKL
报错全文如下:
```text
Error: mkl-service + Intel(R) MKL: MKL_THREADING_LAYER=INTEL is incompatible with libgomp-a34b3233.so.1 library.
Try to import numpy first or set the threading layer accordingly. Set MKL_SERVICE_FORCE_INTEL to force it.
```
可以通过设置环境变量 `MKL_SERVICE_FORCE_INTEL=1` 来解决这个问题。
## 网络
### 运行报错:`('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))` 或 `urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='cdn-lfs.huggingface.co', port=443)`
由于 HuggingFace 的实现OpenCompass 在首次加载某些数据集和模型时需要网络(尤其是与 HuggingFace 的连接)。此外,每次启动时都会连接到 HuggingFace。为了成功运行您可以
- 通过指定环境变量 `http_proxy``https_proxy`,挂上代理;
- 使用其他机器的缓存文件。首先在有 HuggingFace 访问权限的机器上运行实验,然后将缓存文件复制 / 软链到离线的机器上。缓存文件默认位于 `~/.cache/huggingface/`[文档](https://huggingface.co/docs/datasets/cache#cache-directory))。当缓存文件准备好时,您可以在离线模式下启动评估:
```python
HF_DATASETS_OFFLINE=1 TRANSFORMERS_OFFLINE=1 HF_EVALUATE_OFFLINE=1 HF_HUB_OFFLINE=1 python run.py ...
```
这样,评估不再需要网络连接。但是,如果缓存中缺少任何数据集或模型的文件,仍然会引发错误。
- 使用中国大陆内的镜像源,例如 [hf-mirror](https://hf-mirror.com/)
```python
HF_ENDPOINT=https://hf-mirror.com python run.py ...
```
### 我的服务器无法连接到互联网,我如何使用 OpenCompass
如 [网络-Q1](#运行报错Connection-aborted-ConnectionResetError104-Connection-reset-by-peer-或-urllib3exceptionsMaxRetryError-HTTPSConnectionPoolhostcdn-lfshuggingfaceco-port443) 所述,使用其他机器的缓存文件。
## 效率
### 为什么 OpenCompass 将每个评估请求分割成任务?
鉴于大量的评估时间和大量的数据集,对 LLM 模型进行全面的线性评估可能非常耗时。为了解决这个问题OpenCompass 将评估请求分为多个独立的 “任务”。然后,这些任务被派发到各种 GPU 组或节点,实现全并行并最大化计算资源的效率。
### 任务分区是如何工作的?
OpenCompass 中的每个任务代表等待评估的特定模型和数据集部分的组合。OpenCompass 提供了各种任务分区策略,每种策略都针对不同的场景。在推理阶段,主要的分区方法旨在平衡任务大小或计算成本。这种成本是从数据集大小和推理类型中启发式地得出的。
### 为什么在 OpenCompass 上评估 LLM 模型需要更多时间?
请检查:
1. 是否有使用 vllm / lmdeploy 等推理后端,这会大大提速测试过程
2. 对于使用原生 huggingface 跑的,`batch_size` 为 1 会大幅拖慢测试过程,可以适当调大 `batch_size`
3. 如果是 huggingface 上下载的模型,是否有大量的时间卡在网络连接或模型下载上面了
4. 模型的推理结果是否会意外地长,尤其是模型是否在尝试再出若干题并尝试进行解答,这在基座模型中会尤其常见。可以通过在数据集中添加 `stopping_criteria` 的方式来解决
如果上述检查项没有解决问题,请考虑给我们报 bug
## 模型
### 如何使用本地已下好的 Huggingface 模型?
如果您已经提前下载好 Huggingface 的模型文件,请手动指定模型路径. 示例如下
```bash
python run.py --datasets siqa_gen winograd_ppl --hf-type base --hf-path /path/to/model
```
## 数据集
### 如何构建自己的评测数据集
- 客观数据集构建参见:[支持新数据集](../advanced_guides/new_dataset.md)
- 主观数据集构建参见:[主观评测指引](../advanced_guides/subjective_evaluation.md)