基于Qwen 2.5的世界科学智能大赛冠军方案
第二届世界科学智能大赛由上海科学智能研究院与复旦大学联合主办,阿里云协办,以科学智能为风向标,秉持AI赋能千行百业的理念,聚焦五大赛道科技和产业前沿的深入探索。指导机构为上海市科学技术委员会、上海市发展和改革委员会、上海市经济和信息化委员会、上海市教育委员会。
本次赛事共设立生命科学、地球科学、物质科学、社会科学、逻辑推理等五大赛道,其中逻辑推理赛道是唯一一个以“大模型”为主题的竞赛赛道,该赛道主要考验参赛选手通过解决复杂的逻辑推理题,测试大型语言模型的逻辑推理能力。赛题设置上,采用了多样化的逻辑题,涵盖了多种关系和推理规则,覆盖了不同难度的逻辑推理任务,强调了逻辑推理在AI领域的重要性。比赛的研究成果将有助于评估和改进模型的逻辑推理能力,对于开发更智能、更有效的人工智能系统具有重要意义。
- 赛题页面:http://competition.sais.com.cn/competitionDetail/532231/format
- 基座模型权重(Qwen2.5-32B):https://www.modelscope.cn/models/Qwen/Qwen2.5-Coder-32B-Instruct
- 开源模型权重(基于Qwen2.5-32B微调):https://www.modelscope.cn/models/EdisonLeeeee/sais2024_qwen2.5
- 数据集地址(包含合成数据集):https://www.modelscope.cn/datasets/EdisonLeeeee/sais2024_synthetic_data/
- ms-swift项目: https://github.com/modelscope/ms-swift
比赛挑战:
- 逻辑推理能力:逻辑推理题目,解决复杂的推理难题
- 模型泛化性:测试集存在与训练集不同类型的数据样本(题目)
- 模型大小、运行效率:使用docker镜像进行推理,推理显存限制显存32GB,时间4小时(包括镜像下载解压时间)
面对上述挑战,本方案基于通义千问模型,采用多阶段的Easy-to-Hard数据合成方法,模拟人类学习的由简单到困难的思路,逐阶段构造多样化的训练数据。数据生成阶段,训练数据的标签,引入了“Chain-of-Thought”思维链模式,生成多样化的推理路径,逐步对齐推理Scaling Law。训练阶段,采用了LoRA对通义千问32B模型在合成数据集上进行参数高效微调。推理阶段,使用了4bit低精度量化,并结合vLLM框架进行推理加速,最终达到准确性、效率和显存利用率的统一。
数据介绍
本次比赛提供基于自然语言的逻辑推理问题,涉及多样的场景,包括关系预测、数值计算、谜题等,期待选手通过分析推理数据,利用机器学习、深度学习算法或者大语言模型,建立预测模型。
比赛数据集为逻辑推理数据,其中训练集中包含500条训练数据,测试集中包含500条测试数据。每个问题包括若干子问题,每个子问题为单项选择题,选项不定(最多5个)。目标是为每个子问题选择一个正确答案。推理答案基于闭世界假设(closed-world assumption),即未观测事实或者无法推断的事实为假。
具体地,每条训练数据包含 content
, questions
字段,其中content
是题干,questions
为具体的子问题。questions
是一个子问题列表,每个子问题包括options
和answer
字段,其中options
是一个列表,包含具体的选项,按照ABCDE顺序排列,answer
是标准答案。数据集示例如下:
{
'problem': '有一个英文到法文的词汇表,包含以下对应词汇:\n\n1. the -> le\n2. cat -> chat\n3. jumps -> sauts\n4. over -> sur\n5. moon -> lune\n6. cow -> vache\n7. plays -> jouer\n8. fiddle -> violon\n9. egg -> bougre\n10. falls -> des chutes\n11. off -> de\n12. wall -> mur\n\n根据这个词汇表,翻译以下英文句子成法文:',
'questions': [{
'question': '选择题 1:\n英文句子 "the cat jumps over the moon" 翻译成法文是:',
'options': ['le chat saute sur la lune',
'le chat sauts sur le lune',
'le sauts chat sur le lune',
'le chat sauts sur le lune'],
'answer': 'D'},
{
'question': '选择题 2:\n英文句子 "the cow plays the fiddle" 翻译成法文是:',
'options': ['le vache jouer le violon',
'le jouer vache le violon',
'le vache jouer la vièle',
'la vache joue le violon'],
'answer': 'A'},
{
'question': '选择题 3:\n英文句子 "the egg falls off the wall" 翻译成法文是:',
'options': ['le bougre des chutes de le mur',
'le oeuf tombe de le mur',
'le bougre tomber de le mur',
'des chutes le bougre de le mur'],
'answer': 'A'}],
'id': 'round1_train_data_000'}
接下来,我将从Prompt设计,数据合成/增强,模型训练,量化,推理的顺序逐步介绍本次比赛的解决方案。
Prompt设计
本次比赛的核心是让大模型学会做逻辑推理选择题,基于题干「Problem」和问题「Question」,从选项「Options」中选择出答案。因此 ,首先是设计一个合理的Prompt,提取「Problem」,「Question」和「Options」让大模型进行回答。Prompt样例如下:
f"""你是一个逻辑推理专家,擅长解决逻辑推理问题。以下是一个逻辑推理的题目,形式为单项选择题。所有的问题都是(close-world assumption)闭世界假设,即未观测事实都为假。请逐步分析问题并在最后一行输出答案,最后一行的格式为"答案是:A"。题目如下:
### 题目:
{problem}
### 问题:
{question}
{options}
"""
由于每条训练数据有一个「Problem」,但是可能对应多个「Question」和「Options」,因此最终将其拆解成独立的训练数据可以大概得到1400+条数据样本,每条样本的输入就是上述的Prompt文字,输出则为答案对应的选项。
数据合成/增强
本次提出的解决方案的核心在于数据合成与增强,用于提升大模型的逻辑推理能力。采用数据合成的动机源于当前提供的训练集存在以下几个问题:
数据质量较低:训练集中的标签(回复)较为简单,仅提供答案,难以引导大模型生成更加准确的逻辑推理过程。
数据量较少:训练集仅包含1400余条数据,与测试集在分布上存在一定差异(测试集包含未知类型题目),限制了大模型在测试集上的泛化能力。
鉴于本次比赛的逻辑推理题目特点,需要引导模型学习如何组织语言进行推理,因此引入了思维链(Chain-of-Thought, CoT)技术。与直接提供答案的传统训练数据不同,CoT的核心在于通过逐步生成逻辑推理过程(step-by-step)来输出答案。然而,高质量的CoT回复依赖更强大的模型生成,同时直接对原始数据集进行合成存在以下挑战:
高成本:调用GPT-4模型价格昂贵,导致数据合成成本较高。
难度差异:训练集数据难度不均,难以全面提升模型应对不同难度问题的能力。
针对上述问题,本方案提出了多阶段的数据合成策略,通过Easy-to-Hard的方式进行高效的数据合成:
阶段一:首先对训练集的选项进行随机打乱(shuffle),然后使用 Qwen2.5-32B 模型进行CoT推理。如果推理仍然正确,则说明该题较容易;若推理错误,则进入下一阶段。此阶段筛选出约30%-40%的容易数据。
阶段二:对未通过第一阶段的数据,使用商用模型API(如 GPT-4o-mini 和 DeepSeek V2)进行CoT推理生成回复,并判断生成的答案是否正确。此阶段进一步筛选出40%-50%的中等难度数据。
阶段三:针对更难的数据,采用更强的商用模型 GPT-4o 进行CoT推理。如果模型的初次推理结果错误,则执行多次推理,并选取出现次数最多的答案作为最终回复。
通过这种多阶段数据合成策略,不仅显著降低了数据合成的成本,还有效提升了训练数据的覆盖面和质量,从而赋予大模型更强的逻辑推理能力和泛化性能。
该阶段采用的Prompt样例如下:
f"""你是一个逻辑推理专家,擅长解决逻辑推理问题。以下是一个逻辑推理的题目,形式为单项选择题。所有的问题都是(close-world assumption)闭世界假设,即未观测事实都为假。请认真思考,逐步分析问题并在最后一行输出答案,最后一行输出的格式为"答案是:<>"。
### 题目:
{problem}
### 问题:
{question}
{options}
***Instructions***
请根据上述题目和问题,逐步思考推理过程,并最终输出答案。
1. 问题形式为单项选择题,选项中存在且仅存在一个正确答案。
2. 所有的问题都是(close-world assumption)闭世界假设,即未观测事实都为假。
3. 逐步输出思考过程和解答推理过程,过程尽可能简要精炼。
4. 输出为:答案是:<>。
"""
同时,为了赋予大模型更好地测试集泛化能力,本方案进一步设计了数据增强方案,具体的思路是结合训练集的特点,基于同样的「Problem」,引导大模型生成不同的「Question」和「Options」,并生成CoT回复。为了规范大模型的输出格式,在数据增强的过程中,从训练集采样类似的样本提供大模型作为few-shot样本。最终,数据增强的Prompt设计样例如下:
f"""你是一个逻辑推理专家,擅长解决逻辑推理问题。以下是一个逻辑推理的题目:
### 题目
{problem}
### 问题
{question}
{options}
***Instructions***
请根据上述题目,以同样的格式生成类似的题目和相对应的选项,注意:
1. 基于同样的题目,生成不同的问题和选项,选项中必须有且只有一个正确答案。
2. 每次只生成一个问题,形式为单项选择题,确保选项中存在且仅存在一个正确答案。
3. 所有的问题都是(close-world assumption)闭世界假设,即未观测事实都为假。
4. 请认真思考,逐步分析问题并在最后一行输出答案。
5. 输出格式如下:
### 问题
生成的问题
生成的选项
答案
***Example***
### 问题
{question}
{options}
{answer}
"""
在该数据合成/增强阶段,本方案使用了GPT-4o-mini,GPT-4o,DeepSeek,Qwen等模型的API,对于不同的API调用采用不一样的prompt,从而生成更加多样性的回复标签。
模型训练
针对合成好的数据集,采用ms-swift框架进行微调。SWIFT(Scalable lightWeight Infrastructure for Fine-Tuning)是魔搭ModelScope开源社区推出的一套完整的轻量级训练推理工具,基于PyTorch的轻量级、开箱即用的模型微调、推理框架,让AI爱好者用自己的消费级显卡就能玩转大模型和AIGC。
本方案采用LoRA进行参数高效微调,微调命令如下:
swift sft \
--model_type qwen2_5-32b-instruct \
--model_id_or_path /root/autodl-tmp/Qwen2.5-32B-Instruct \
--model_revision master \
--sft_type lora \
--template_type AUTO \
--dtype bf16 \
--output_dir /root/autodl-tmp/qwen \
--dataset $TRAIN_DATA \
--num_train_epochs 3 \
--max_length 4096 \
--check_dataset_strategy warning \
--lora_target_modules ALL \
--gradient_checkpointing true \
--lora_rank 256 \
--lora_alpha 512 \
--batch_size 1 \
--learning_rate 1e-4 \
--gradient_accumulation_steps 8 \
--max_grad_norm 1.0 \
--warmup_ratio 0.03 \
--save_steps 2000 \
--save_total_limit 3 \
--use_flash_attn true \
--save_only_model true \
--logging_steps 100
注:本方案采用的ms-swift版本为2.5.2,当前ms-swift最新版本3.x版本的训练/推理命令有较大改动。
其中,TRAIN_DATA
为给定的合成数据集。基于同样的训练命令,指定不同的数据集进行训练得到不同的模型,这里只需要修改-dataset
参数指定不同的数据集TRAIN_DATA
即可。
模型量化
由于比赛限定的显存是32G,而Qwen2.5-32B模型推理需要的显存将近80G,因此需要对训练好的模型进行量化。在量化之前需要先进行LoRA参数合并:
swift export \
--model_type qwen2_5-32b-instruct \
--model_id_or_path /root/autodl-tmp/Qwen2.5-32B-Instruct \
--ckpt_dir $OUTPUT_DIR \
--dtype fp16 \
--merge_device_map auto \
--merge_lora true
这里的$OUTPUT_DIR
需要指定训练好的LoRA权重路径。模型合并成一个完整的新模型后,下一步就是进行量化。本方案采用的量化方法是gptq
进行4bit量化,在比赛过程中该量化方案损失最小,量化运行的代码如下:
swift export \
--model_type qwen2_5-32b-instruct \
--quant_bits 4 \
--quant_method gptq
--model_id_or_path $OUTPUT_DIR-merged \
--dataset $TRAIN_DATA alpaca-zh alpaca-en sharegpt-gpt4:default \
这里的OUTPUT_DIR-merged
就是上述合并后的模型路径。gptq量化还需要选择校准的数据集,这里本方案使用的是训练集TRAIN_DATA
和公开的数据集alpaca-zh alpaca-en sharegpt-gpt4:default
进行量化,量化的精度为4bit。
量化完成后,模型的运行显存大大降低,大约为20GB,足够在32GB的环境下进行推理。
模型推理
由于模型在训练过程中采用的CoT方式训练,在推理过程也会具备思维链式推理的能力,虽然极大地增强了模型的推理能力,但也牺牲了推理的速度(输出的token数目变多了导致速度变慢)。具体来讲,从原来输出的个位数token以内变成上百上千的token,大大降低了模型的推理速度。根据实验,即使是经过量化后的Qwen 2.5-32B模型在测试集上推理也需要将近3-4h的时间。为了加快推理速度,本方案采用了vLLM进行加速推理。vLLM(Vectorized Large Language Model Serving System)是一个大型语言模型推理加速工具,它通过优化内存管理、连续批处理、CUDA核心优化和分布式推理支持等技术手段,显著提高了大型语言模型的推理速度和效率。本方案采用的vLLM推理代码如下:
from swift.llm import (
ModelType, get_vllm_engine, get_default_template_type,
get_template, inference_vllm, inference_stream_vllm
)
def chat_swift(texts, model_path,
model_type='qwen2_5_32b_instruct',
max_tokens=2048,
max_model_len=2048,
temperature=0.1,
top_p=0.7,
top_k=20,
use_tqdm=True,
**kwargs):
model_type = getattr(ModelType, model_type)
llm_engine = get_vllm_engine(model_type, model_id_or_path=model_path, **kwargs)
template_type = get_default_template_type(model_type)
template = get_template(template_type, llm_engine.hf_tokenizer)
llm_engine.generation_config.max_new_tokens = max_tokens
llm_engine.generation_config.temperature = temperature
llm_engine.generation_config.top_p = top_p
llm_engine.generation_config.top_k = top_k
generation_info = {
}
request_list = [{
'query': x} for x in texts]
outputs = inference_vllm(llm_engine, template, request_list, generation_info=generation_info, use_tqdm=use_tqdm)
print(generation_info)
outputs = [out['response'] for out in outputs]
return outputs
# vllm调用
# prompts为构造好的测试集问题prompt
# model_path 为量化后的模型路径
outputs = chat_swift(prompts, model_path, quantization='gptq')
最终,经过vLLM优化,模型的推理时间降到了30-40min,对于4h的推理时间还有很大的空余,因此可以考虑进行多个模型集成。
模型集成
本方案训练得到了四个模型,单模的效果分别为:0.8769,0.8894,0.8823, 0.8752,其中最优的0.8894是基于GPT-4o的API合成的数据,训练得到的模型效果远远优于其他数据、由于模型之间性能差别较大,简单地进行投票融合容易「拖累」最优模型的效果,因此本方案采用了新的一致性集成方式:当三个较差的模型答案一致时,则采纳其答案,否则采纳最优模型的答案。具体的代码如下所示:
def ensemble(answers):
# answers 为四个模型的预测答案,第0位为最优模型的答案
a = answers[0]
b = np.unique(answers[1:])
if len(b) == 1:
return b[0]
return a
训练好的模型链接:https://www.modelscope.cn/models/EdisonLeeeee/sais2024_qwen2.5
其中,四个模型对应的终榜准确率为:
V2: 0.8769
V4: 0.8894
v6: 0.8823
v8: 0.8752
总结
本方案介绍了第二届世界科学智能大赛的冠军方案,方案基于通义千问2.5模型进行微调、量化和推理,通过大模型进行数据合成与增强提高泛化能力与逻辑推理能力,最终在终榜上取得了第一名的成绩。