T1 小小数学助手

故事背景

你来到小学帮助小朋友学数学。孩子们每天都会来问你各种数学题:

  • 有的小朋友只想知道简单的加减乘除结果;
  • 有的小朋友希望你一次性帮他算一整页的练习题;
  • 还有的小朋友要求答案统一、整齐,不要多余的话,这样才能方便对照答案本子。

不过,这里的小朋友们写题目时非常"自由"。有的在纸上写正常的 +-,有的画奇怪的符号,比如 ,甚至还有人用中文"加""减"。如果直接用普通计算器,往往认不出这些符号,会算错。

于是,你决定编写一个小小数学助手,让它能够理解孩子们各种各样的题目,并用统一的答案格式来回答。这个助手基于 PyTorchTransformers 库,可以自动回答孩子们提出的数学问题。

任务目标

你需要在 submission.py 中完成三个核心函数,让数学助手具备以下能力:

1. 定义回答规则:build_system_prompt() -> str

编写一个 system prompt,引导模型识别各种数学符号并按照 [Answer]: 数值 的格式输出答案。

2. 构造对话模板:apply_chat_template_single(...) -> str

使用 tokenizer 将 system prompt 和用户问题组合成模型能理解的输入格式。

3. 实现推理:generate_single(...)generate_batch(...)

实现单条推理和批量推理两种模式,返回模型生成的 token 序列。

注意:直接返回模型原始输出,不要做后处理。评测程序会统一处理输出格式。

实现要求

文件结构

T1/
├── data/
│   ├── test_data_1.jsonl    # 阶段一测试数据(8题)
│   └── test_data_2.jsonl    # 阶段二测试数据(32题)
├── evaluate.py              # 评测主程序(不可修改)
├── submission.py            # 考生实现文件(仅此文件可修改)
└── README.md                # 本文档

修改规则

  • 仅可修改 submission.py 中标注的"考生实现区域"
  • ✅ 可以新增少量辅助函数
  • 不得修改 evaluate.py 的任何内容
  • 不得在函数中做答案后处理(如提取数字、格式转换等)

技术要求

  • 使用 PyTorch 和 Transformers 库
  • 正确处理 tokenizer 的 padding 和 truncation
  • 批量推理需要考虑内存和效率

评测说明

运行方式

演示模式(详细输出)

python evaluate.py
# 或
python evaluate.py --mode demo
  • 展示每个题目的完整推理过程
  • 显示模型原始输出、处理后文本、提取的答案
  • 展示错误样例的详细信息

评分模式(简洁输出)

python evaluate.py --mode grading
  • 简洁的进度输出
  • 最终输出详细评分和性能指标
  • 用于正式评测

评测流程

阶段一:逐条推理(8 题)

测试内容

  • 固定的 8 道数学题(基础四则运算 + 特殊符号)
  • 逐条调用 generate_single 进行推理
  • 测试模型对各种符号和表达的理解能力

示例题目

{"problem": "12 + 35", "answer": "47"}
{"problem": "6的平方?", "answer": "36"}
{"problem": "45 加 89", "answer": "134"}

输出内容(Demo 模式):

  • 题目原文
  • 模型原始输出(可能包含 <think> 标签)
  • 非思考部分文本
  • 提取的答案
  • 判定结果(✅/❌)
  • 单题耗时

评分标准

  • 正确性:每题 10 分,答对 ≥6 题给满分 60 分

阶段二:批量推理(32 题)

测试内容

  • 32 道数学题(包含多种符号和表达)
  • 调用 generate_batch 进行批量推理
  • 测试批量处理的效率和准确性

示例题目

{"problem": "91 + 24", "answer": "115"}
{"problem": "34 ⊕ 19", "answer": "53"}
{"problem": "47 - 41", "answer": "6"}

输出内容(Demo 模式):

  • 仅展示错误的样例(正确的不显示)
  • 全部正确时显示祝贺信息

评分标准

  • 正确性:每题 1.5 分,答对题数 × 1.5 分,满分 40 分

总分构成(100 分)



T2 多样性数据生成与相似度计算

故事背景

你正在为一个在线学习平台开发智能题库系统。为了让学生能够充分练习,题库需要满足两个核心要求:

  • 准确的相似度判断:能够识别题目之间的相似程度,避免重复练习相同的题目
  • 多样化的题目生成:能够生成大量风格各异的题目,让学生接触到不同的表达方式

然而,题目的相似度判断并不简单。同样是 12 + 35 这道题,可能会有很多种表达方式:

  • 符号变体:12+3512 ⊕ 35
  • 顺序变化:35 + 12
  • 文字表达:12 加 35计算:12 加 35

你需要实现一个能够准确计算文本相似度的函数,并基于此生成一批高质量、多样化的数学题目数据集。

任务目标

你需要完成两个核心任务:

1. 实现相似度计算:compute_similarity(text1, text2, model, tokenizer) -> float

编写一个函数,使用给定的 embedding 模型计算两个文本的余弦相似度。

技术要点

  • Last-token pooling(提取最后一个 token 的 hidden state)
  • L2 normalization(归一化向量)
  • 余弦相似度(归一化后的点积)

2. 生成多样化数据集:data/dataset.jsonl

生成 1024 条高质量的数学题目数据,满足以下要求:

  • 所有题目唯一(无重复)
  • 每个题目最多 3 个数字
  • 答案为 3 位数(100-999)
  • 平均相似度 ≤ 0.5(越低越好)

实现要求

文件结构

T2/
├── data/
│   ├── test_data_1.jsonl    # 相似度测试用例(10组)
│   └── dataset.jsonl         # 考生生成的数据集(1024条)
├── evaluate.py              # 评测主程序(不可修改)
├── submission.py            # 考生实现文件(仅此文件可修改)
└── README.md                # 本文档

修改规则

  • 仅可修改 submission.py 中的 compute_similarity 函数
  • ✅ 可以新增辅助函数用于数据生成
  • 必须生成 data/dataset.jsonl 文件(1024条数据)
  • 不得修改 evaluate.py 的任何内容
  • 不得修改 data/test_data_1.jsonl 测试用例

技术要求

相似度计算

  • 使用 PyTorch 和 Transformers 库
  • 正确实现 last-token pooling
  • 正确实现 L2 normalization
  • 返回值范围:[0, 1]

数据生成

  • JSON Lines 格式:每行一个 JSON 对象
  • 必需字段:problem(题目)、answer(答案)
  • 题目示例:{"problem": "12 + 35", "answer": "47"}

评测说明

运行方式

演示模式(详细输出)

python evaluate.py
# 或
python evaluate.py --mode demo
  • 展示每个测试用例的详细结果
  • 显示数据多样性的详细统计
  • 显示扣分明细和最终得分

评分模式(简洁输出)

python evaluate.py --mode grading
  • 简洁的进度输出
  • 最终输出详细评分
  • 用于正式评测

评测流程

第一部分:相似度计算准确性(50 分)

测试内容

  • 10 组预定义的文本对测试用例
  • 使用预计算的标准相似度进行对比
  • 测试模型对各种相似度的判断能力

示例测试用例

{"text1": "12 + 35", "text2": "12 + 35", "description": "完全相同", "standard_similarity": 1.0}
{"text1": "12 + 35", "text2": "12+35", "description": "符号不同", "standard_similarity": 0.877}
{"text1": "12 + 35", "text2": "35 + 12", "description": "顺序不同", "standard_similarity": 0.869}

输出内容(Demo 模式):

  • 测试用例描述
  • 两个输入文本
  • 标准相似度
  • 考生计算的相似度
  • 误差值
  • 判定结果(✅/❌)

评分标准

  • 每个测试用例 5 分,共 10 组
  • 允许误差:≤ 0.03
  • 通过 ≥ 8 组:满分 50 分
  • ⚠️ 必须满分才能进行第二部分测试

第二部分:数据多样性(50 分)

前提条件:第一部分必须获得满分(50分)

测试内容

  • 加载 data/dataset.jsonl 数据集
  • 检查数据数量、质量
  • 使用考生的模型计算数据集的平均相似度

数据要求

  1. 数量要求:1024 条

    • 每少/多 1 条扣 1 分
  2. 质量要求(每条问题扣 1 分):

    • 所有题目必须唯一(不能有重复)
    • 所有题目非空
    • 每个题目最多 3 个数字
    • 答案必须是 3 位数(100-999)
  3. 相似度要求

    • ≤ 0.5:满分 50 分
    • 0.5 ~ 0.7:线性给分
    • 0.7:0 分

示例数据

{"problem": "818 ⊖ 10 减 89", "answer": "719"}
{"problem": "(98 - 30) 乘 9", "answer": "612"}
{"problem": "28 乘 19 / 4", "answer": "133"}

输出内容(Demo 模式):

  • 数据数量统计
  • 唯一性检查
  • 数字个数检查
  • 答案位数检查
  • 平均相似度统计
  • 扣分明细
  • 最终得分

评分公式

相似度得分:
  - 平均相似度 ≤ 0.5:50 分
  - 平均相似度 0.5~0.7:int(50 * (0.7 - avg_sim) / 0.2)
  - 平均相似度 > 0.7:0 分

最终得分 = max(0, 相似度得分 - 数量扣分 - 质量扣分)

总分构成(100 分)

项目 分值 说明
第一部分 - 相似度计算 50 分 10组测试用例,每组5分,≥8组满分
第二部分 - 数据质量 0~50 分 数量扣分 + 质量扣分
第二部分 - 相似度评分 基于平均相似度
最终得分 0~100 分 第一部分 + 第二部分(最低0分)

⚠️ 重要提示

  • 第一部分未满分 → 第二部分跳过 → 总分最多 50 分
  • 第二部分得分 = 相似度得分 - 数量扣分 - 质量扣分(最低0分)