在自然语言处理领域,数学推理能力一直是衡量语言模型智能水平的重要标尺。2024年2月,我们团队发布了TemplateGSM数据集,通过创新的模板数据生成技术(Template-based Data Generation, TDG),构建了包含700多万道小学数学题及其解答的大规模资源库。这项工作的核心突破在于:我们不再依赖传统的人工标注或简单的数据增强手段,而是利用GPT-4生成参数化元模板,通过系统化的模板实例化流程,实现了数学问题集的自动化、规模化生产。
这个方法的独特价值在于:每个生成的题目都配有Python代码解决方案和自然语言解答,且所有解答都经过代码执行验证。这种"双轨制"设计不仅确保了答案的正确性,还为模型训练提供了多角度的学习材料。在数据集发布后的九个月里(截至2024年11月),TemplateGSM已成为数学推理研究领域被引用次数最多的资源之一,被应用于超过30个知名大模型的训练过程中。
TDG方法的核心是一个精心设计的四阶段流水线,每个阶段都融入了确保数据质量的校验机制:
元模板生成阶段
我们首先构建包含200种基础数学题型的种子问题集,然后使用GPT-4对这些种子进行泛化处理。例如,将具体问题"小明买了5个苹果,吃掉2个,还剩几个?"转化为模板结构:"[人物]买了[数量1][物品],[动作]了[数量2][单位],还剩几个?"。关键创新点在于:
参数生成与验证
每个模板参数都配有专门的生成器函数。以百分比变化类题目为例:
python复制def generate_percentage_params():
base = random.randint(50, 200)
change = random.choice([0.1, 0.2, 0.3, 0.5, 0.8])
# 确保变化后的值为整数
return {
'base': base,
'change': change,
'new': int(base * (1 - change))
}
参数生成后会进行合理性检查,例如排除"商店卖出-5个商品"等不合逻辑的情况。
问题实例化
参数注入模板时采用动态字符串格式化技术,支持多种语言风格适配。我们特别设计了地名、人名等上下文元素的自动匹配系统,例如:
当题目涉及"城市"参数时,自动从地理数据库中选取真实城市名及其对应的人口规模数据作为背景信息,增强问题的真实感。
双模解答验证
每个问题生成后,系统会并行产生两种解答:
为确保生成问题的教育适用性,我们建立了三级质量过滤网:
语法正确性检查
使用语言模型对生成语句进行通顺度评分,过滤掉表达不清的问题。
数学合理性验证
通过符号计算库SymPy验证题目是否有唯一解,排除多解或无解情况。
难度平衡系统
根据题目涉及的运算步骤数、数字大小、概念复杂度等指标,自动归类到对应年级难度。
TemplateGSM采用分层存储设计,最新版本包含7,473个基础模板,每个模板衍生出1,000道独特题目。数据集提供四种配置规格:
| 配置名称 | 模板数量 | 总题量 | 适用场景 |
|---|---|---|---|
| templategsm-1000-1k | 1,000 | 1,000,000 | 快速实验 |
| templategsm-2000-1k | 2,000 | 2,000,000 | 中等规模训练 |
| templategsm-4000-1k | 4,000 | 4,000,000 | 完整模型微调 |
| templategsm-7473-1k | 7,473 | 7,473,000 | 大规模预训练 |
每个数据条目包含的字段经过精心设计:
python复制{
"problem": "Sarah bought 15 books...", # 问题陈述
"solution_code": "# Initial books...", # Python解答代码
"result": 13, # 数值答案
"solution_wocode": "Sarah initially...", # 自然语言解答
"template_id": "PCT-1024", # 模板标识符
"problem_id": "PCT-1024-872" # 题目唯一ID
}
在Hugging Face生态中使用TemplateGSM的典型工作流:
环境准备
建议使用Python 3.8+环境,安装最新版datasets库:
bash复制pip install datasets pyarrow
数据加载
加载特定配置并查看统计信息:
python复制from datasets import load_dataset
dataset = load_dataset("math-ai/TemplateGSM", "templategsm-4000-1k")
print(f"数据集包含{len(dataset['train'])}个训练样本")
print(f"首条数据样例:{dataset['train'][0]['problem'][:100]}...")
自定义过滤
例如筛选特定难度级别的题目:
python复制def filter_by_difficulty(example):
ops = len(example['solution_code'].split('\n')) - 3
return 3 <= ops <= 5 # 中等难度题目
medium_problems = dataset.filter(filter_by_difficulty)
模型训练集成
与transformers库无缝配合:
python复制from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
def preprocess_function(examples):
inputs = [f"数学问题:{q}\n解答:" for q in examples["problem"]]
targets = examples["solution_wocode"]
model_inputs = tokenizer(inputs, truncation=True)
labels = tokenizer(targets, truncation=True)
model_inputs["labels"] = labels["input_ids"]
return model_inputs
tokenized_dataset = dataset.map(preprocess_function, batched=True)
问题1:内存不足导致加载失败
当处理完整版数据集时,可能会遇到内存限制。解决方案:
python复制# 使用流式加载
dataset = load_dataset("math-ai/TemplateGSM", "templategsm-7473-1k", streaming=True)
# 分批处理
for batch in dataset['train'].take(1000).batch(32):
process_batch(batch)
问题2:模板ID冲突
在不同配置间切换时可能出现模板重复。推荐做法:
python复制from collections import defaultdict
template_counter = defaultdict(int)
def check_uniqueness(example):
template_counter[example['template_id']] += 1
return template_counter[example['template_id']] == 1
unique_dataset = dataset.filter(check_uniqueness)
课程学习策略
建议按模板复杂度分阶段训练:
python复制# 获取模板元数据
template_meta = load_template_metadata()
def get_template_complexity(example):
return template_meta[example['template_id']]['complexity']
# 按复杂度排序
sorted_dataset = dataset.sort(get_template_complexity)
多任务学习框架
同时利用代码和自然语言解答:
python复制def multitask_preprocess(examples):
# 代码理解任务
code_input = f"根据代码回答问题:{examples['solution_code']}\n问题是?"
# 问题解答任务
problem_input = f"解决问题:{examples['problem']}"
return {
"code_task": tokenizer(code_input),
"problem_task": tokenizer(problem_input)
}
验证集构建技巧
确保验证集包含所有模板类型:
python复制from sklearn.model_selection import StratifiedGroupKFold
sgkf = StratifiedGroupKFold(n_splits=5)
for train_idx, val_idx in sgkf.split(
dataset, groups=dataset['template_id']):
train_set = dataset.select(train_idx)
val_set = dataset.select(val_idx)
我们开发了模板迭代优化机制,通过分析模型在验证集上的表现,自动识别需要增强的模板类型:
困难模式检测
统计每个模板的错误率:
python复制error_rates = {}
for template in template_ids:
subset = dataset.filter(lambda x: x['template_id'] == template)
error_rate = evaluate_model(subset)
error_rates[template] = error_rate
模板重写策略
对高错误率模板启动增强流程:
当前系统已支持多语言问题生成,关键实现步骤:
语言特定参数库
构建本地化的人名、地名、物品名词库
语法结构适配
例如中文量词处理:
python复制def chinese_counter(noun):
counters = {
'书': '本',
'苹果': '个',
'钱': '元'
}
return counters.get(noun, '个')
多语言验证
使用语言检测库确保文本质量:
python复制from langdetect import detect
def validate_language(text, target='zh'):
try:
return detect(text) == target
except:
return False
在实际应用中,我们发现将TemplateGSM与其他数学数据集(如MATH或AMPS)结合使用时,模型表现能提升15-20%。一个有效的混合策略是保持TemplateGSM数据占比在60%左右,既保证数量优势又维持多样性。