> ## Documentation Index
> Fetch the complete documentation index at: https://starforge.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Benchmark 包

> 声明一个评测集：跑什么、读哪些数、怎么读。

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
sf bench new my-bench            # 生成一个包的骨架
sf plugin publish ./my-bench     # 发布
sf bench ls                      # 它已经在 catalog 里
sf bench run my-bench -m run:run-4f2a91
```

一个 benchmark 包用 YAML 回答三个问题，且不含任何代码：**跑什么**、**读哪些数**、**默认怎么跑**。
真正执行的是随 SDK 发版的 runner。

## 目录结构

```text theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
my-bench/
├── plugin.yaml       # kind: benchmark
├── benchmark.yaml    # 声明本体
└── README.md
```

## benchmark.yaml

```yaml benchmark.yaml theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
schema: forge/benchmark/v1
name: gsm8k
title: GSM8K · Grade-school math word problems
category: math
summary: >
  8.5K grade-school math word problems requiring 2-8 reasoning steps.

runner: lm-eval
suites: [gsm8k]
num_fewshot: 5
batch_size: auto
keywords: [math, reasoning, cot]

metrics:
  - key: exact_match,strict-match
    label: Exact match (strict)
    i18n:
      zh:
        label: 精确匹配（严格）
    primary: true
  - key: exact_match,flexible-extract
    label: Exact match (flexible)
    i18n:
      zh:
        label: 精确匹配（宽松）

i18n:
  zh:
    title: GSM8K · 小学数学应用题
    summary: >
      8.5K 道小学数学应用题，需要 2-8 步推理。数学类后训练最常用的入门基准。
```

### 字段

<ParamField path="name" type="string" required>
  叶子名。已发布的包引用形式是 `<owner>.<name>`；内置的保持裸名。
</ParamField>

<ParamField path="runner" type="lm-eval | evalscope | rtl | judge | safety" required>
  哪个 harness 执行评测。见下表。
</ParamField>

<ParamField path="suites" type="string[]" required>
  runner 认识的 suite 名。对 `lm-eval` 来说就是它的 task 名。
</ParamField>

<ParamField path="category" type="string" default="general">
  看板分区——`math`、`code`、`knowledge`、`chinese`、`instruction` 等。
</ParamField>

<ParamField path="num_fewshot, batch_size, limit, extra_args" type="mixed">
  跑它的默认参数。`batch_size` 默认 `auto`，`limit` 限制样本数。用户提交时都能覆盖；
  你声明的是「不加任何参数时该是什么」。

  这正是包存在的意义：不该有人需要记住 GSM8K 要 5-shot，或者 HumanEval 需要
  `--confirm_run_unsafe_code`。
</ParamField>

<ParamField path="rubric" type="<owner>/<name>">
  只有 `judge` runner 读它，而对那个 runner 来说它**就是**这个 benchmark 的定义。
  换个 rubric 就是另一个 benchmark——所以它是一个声明字段，
  而不是埋在 `extra_args` 里、从 catalog 上看不见的一个 flag。
</ParamField>

### 指标

每一条说明从 runner 的报告里取哪个数、怎么呈现它。

<ParamField path="key" type="string" required>
  runner 产出的原始 metric 名，一字不差——lm-eval 的 `exact_match,strict-match`。
  这是给机器看的名字，不可翻译。
</ParamField>

<ParamField path="label" type="string">
  看板列头显示什么。默认取 `key`——那对机器够用，对人不够。
</ParamField>

<ParamField path="direction" type="higher | lower | neutral" default="higher">
  哪个方向算好。对比视图据此给回退上色。
</ParamField>

<ParamField path="ratio" type="bool" default="true">
  值是不是 0–1 的占比，决定看板按不按百分比渲染。
</ParamField>

<ParamField path="primary" type="bool" default="false">
  跨 run 对比默认看的那个指标。应当恰好有一个是 primary；一个都没有时取第一个。
</ParamField>

<Tip>
  当两个指标之间的差本身有诊断价值时，就都声明出来。GSM8K 的严格与宽松匹配是标准例子：
  严格分低而宽松分高，说明模型会算，但输出格式没按要求来——那是 prompt 问题，不是能力问题。
  只留一个数就把这件事藏起来了。
</Tip>

## 五个 runner

| Runner      | 跑的是什么                            | 什么时候用                     |
| ----------- | -------------------------------- | ------------------------- |
| `lm-eval`   | EleutherAI lm-evaluation-harness | 学术标准基准。默认选它               |
| `evalscope` | ModelScope evalscope             | 中文基准——C-Eval、CMMLU——它覆盖更好 |
| `rtl`       | evalkit 镜像里固定的 RTL / 硬件 harness  | Verilog 与硬件设计类 suite      |
| `judge`     | 用 vLLM 生成，由平台裁判打分                | 规则打不了分的东西。需要 `rubric`     |
| `safety`    | 拒答 suite，按 rubric 打分             | 该拒的模型有没有拒                 |

<Note>
  `lm-eval` 和 `evalscope` 用规则判对错——精确匹配、解析答案。`judge` 和 `safety`
  用你的团队写的 rubric 判。后两者的 suite 策略和 rubric 内容平台都不提供：
  它们属于部署方，平台内置任何一个都等于替别人下了一个它没资格下的结论。
</Note>

## 双语展示文案

manifest 用英文写，翻译放 `i18n:` 块——包级和每个 metric 上都可以：

```yaml theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
metrics:
  - key: exact_match,strict-match
    label: Exact match (strict)
    i18n:
      zh:
        label: 精确匹配（严格）
    primary: true
```

只有展示文案可翻译。id、suites 和 metric key 是契约，任何语言下都必须一致。

## 确认成功

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
sf bench ls                                    # 你的包，带 runner 和指标
sf bench run my-bench -m run:run-4f2a91        # 给一次完成的 run 打分
```

分数落在控制台的 Benchmarks 页，和所有内置基准在同一个矩阵里，
所以同一个 run 上你的分数可以和 GSM8K、MMLU 直接比较。

## 在外部打分的基准

打分发生在平台够不到的地方时——有授权限制的 harness、真实的测试台架——
不要在这里跑，把分数报回来：

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
sf bench external create --name my-rig-eval -m run:run-4f2a91
sf bench external submit <EVAL_ID> --scores scores.json
```

分数进同一个矩阵，并标记为外部产生。围绕它的完整流程见[运行评测](/zh-Hans/guides/benchmarks)。

## 内置了哪些

`gsm8k`、`math`、`humaneval`、`mmlu`、`ceval`、`ifeval`，以及 RTL 系列
（`rtl-repo`、`rtllm-v2`、`verilogeval-v2`、`verilogeval-v2-completion`、`cvdp`）。

这几个轴是刻意挑的：数学、代码、知识回退、中文、指令遵循。
后训练最常见的情况是「改好了一个，悄悄弄坏了另一个」，
同时跑好几个的意义就是让这件事在一屏之内可见。
