
用 GRPO 给 Text-to-SQL 模型装上“推理引擎”,让语言模型不只是生成代码! 原创 精华
在人工智能的世界里,语言模型的智能程度越来越高,但如何让它们真正理解并解释自己的决策过程,依然是一个难题。今天,我们来聊聊一个非常有趣的话题:如何通过一种名为 GRPO(Guided Reward Policy Optimization,引导式奖励策略优化)的技术,将一个普通的 7B 参数语言模型(Qwen2.5-Coder-7B-Instruct)变成一个能够进行结构化推理的 Text-to-SQL 模型。
为什么 GRPO 是 Text-to-SQL 的完美选择?
如果你对 AI 领域有所关注,可能已经听说过 GRPO。这是 DeepSeek 提出的一种强化学习技术,主要用于训练推理模型。而 Text-to-SQL 任务,简直就是为 GRPO 量身定制的!
推理的重要性:SQL 不仅仅是语法
SQL 是一种结构化的逻辑语言,而不是简单的语法组合。通过 GRPO,模型被鼓励解释为什么选择某些表、连接或过滤条件,从而让模型像人类分析师一样“思考”,更贴近用户的真实意图。比如,当你问“上个月活跃用户是谁”时,模型不能简单地返回 SELECT * FROM users
,而是要解释清楚为什么这么写。
捕捉“沉默的错误”
没有推理的模型可能会犯一些很微妙的错误。比如,问题明明是“上个月活跃用户”,结果模型返回了一个看似正确的 SQL,但其实并没有考虑到时间范围。GRPO 的双重奖励系统(推理 + SQL)可以早期发现这些不匹配的问题。
小模型也需要“扶手”
对于像 7B 这样的小模型来说,复杂的逻辑是一个巨大的挑战。GRPO 就像是给模型装上了“扶手”,通过奖励连贯的逐步推理,惩罚不合理的输出,即使 SQL 看起来没问题,也能确保模型的逻辑是合理的。
透明性建立信任
如果模型能写出“我使用了‘购买’表,因为问题问的是销售情况”,那么调试和验证就会变得容易得多。GRPO 把这种清晰性直接融入了训练过程。
如何设计奖励函数?
Text-to-SQL 推理的挑战在于如何创建有效的奖励函数,既能评估解释的质量,又能确保生成的 SQL 是准确的。为此,我们设计了多部分奖励函数,每部分都捕捉模型行为的一个关键方面。这些奖励函数被用于通过 Unsloth 框架对 7B 模型进行微调。
奖励函数详解
- 格式奖励(soft_format_reward_func):权重 1.0。这个简单的函数检查输出是否符合
<reasoning>...</reasoning><sql>...</sql>
的格式。如果匹配,返回完整的格式奖励权重(默认 1.0),否则为 0。
- 复杂度奖励(complexity_reward):权重 0.6。这个奖励确保生成的 SQL 的复杂度与标准答案(gold SQL)一致,避免过于简单或过于复杂。如果没有标准答案,复杂度在 [1.5, 8.0] 范围内得 0.4 倍权重,否则得 0.1 倍权重。如果有标准答案,则使用高斯相似性计算,基于复杂度比值的对数。
- 推理质量奖励(reasoning_quality_reward):权重 0.7。这个奖励函数评估模型生成的推理部分的质量,使用一系列启发式规则来反映人类的分析性思维。奖励由多个组件分数组成,包括推理长度、SQL 术语使用、结构清晰度、步骤指示和模式提及等。
- 执行查询奖励(execute_query_reward_func):权重 1.2。这是最重要的奖励,测试生成的 SQL 是否能够实际运行并产生正确的结果。对于 SELECT 语句,如果执行成功得 0.3 倍权重,结果完全匹配得满分。对于部分匹配,使用 Jaccard 相似性计算。对于 DML 语句(INSERT、UPDATE、DELETE),成功执行得 0.5 倍权重,需要大小写修正得 0.4 倍权重。
在 GRPO 训练中实现这些奖励函数
以下是使用 Unsloth 设置这些奖励函数的代码示例:
from trl import GRPOConfig, GRPOTrainer
# 配置训练参数
training_args = GRPOConfig(
use_vllm=True,
learning_rate=5e-6,
per_device_train_batch_size=1,
gradient_accumulation_steps=1,
num_generatinotallow=8,
max_prompt_length=256,
max_completion_length=200,
max_steps=250,
output_dir="outputs",
...
)
trainer = GRPOTrainer(
model=model,
processing_class=tokenizer,
reward_funcs=[
soft_format_reward_func,
execute_query_reward_func,
reasoning_quality_reward,
complexity_reward,
],
args=training_args,
train_dataset=dataset,
)
trainer.train()
系统提示应该明确指示模型使用推理:
你是一个将自然语言问题转换为 SQL 查询的 AI 助手。
给定数据库模式和一个问题,生成正确的 SQL 查询。
请严格按照以下格式回答,包括 <reasoning> 和 <sql> 标签:
<reasoning>
逐步思考以理解数据库模式和问题。
识别必要的表、列、连接和条件。
解释构建 SQL 查询的逻辑。
</reasoning>
<sql>
-- 你的 SQL 查询
</sql>
评估奖励系统的有效性
为了评估这些多维度奖励函数的效果,我们使用了 LLM-as-a-Judge 方法,让 GPT-4o-mini 作为专家评委,对微调后的模型在 SQL 准确性和推理质量上进行评估。
评估数据集包含 50 个随机选择的示例,评估维度包括四个关键方面,评分范围为 1-5:
- SQL 准确性:生成的 SQL 是否准确有效?
- 推理质量:推理是否清晰、逻辑合理且引用了正确的模式?
- 格式遵循:是否遵循
<reasoning>...</reasoning><sql>...</sql>
的格式? - 教育价值:是否有助于学习 SQL 概念?
评估提示如下:
作为一名 SQL 专家,请评估以下文本到 SQL 的转换。每个维度的评分范围为 1-5(1=差,5=优秀)。
数据库模式:
{sample['sql_context']}
问题:
{sample['sql_prompt']}
标准 SQL(正确):
{sample['sql']}
模型输出:
{sample['model_output']}
请按照以下格式提供评分:
SQL_SCORE: [1-5] - SQL 是否有效并产生正确结果?
REASONING_SCORE: [1-5] - 推理是否清晰、逻辑合理且引用了正确的模式?
FORMAT_SCORE: [1-5] - 是否遵循 <reasoning>...</reasoning><sql>...</sql> 格式?
EDUCATIONAL_SCORE: [1-5] - 是否有助于学习 SQL?
OVERALL_SCORE: [平均分]
EXPLANATION: [简要说明优缺点]
ERROR_TYPE: [none/syntax/logic/format/other]
评估结果
经过微调的 Qwen2.5-Coder-7B-Instruct 模型在仅使用 300 个示例进行训练、250 步训练后,取得了令人满意的结果:
- SQL 准确性:44/50 的输出得分在 4 或 5 分,表现出色。
- 推理质量:48/50 的输出得分在 4 或 5 分,推理清晰且逻辑合理。
- 格式遵循:49/50 的输出得分达到 5 分,格式几乎完美。
- 教育价值:模型输出对学习 SQL 概念有明显帮助。
总体来看,88% 的输出得分在 4.0 或以上,显示出模型在结构化推理和可解释性方面的一致性和可靠性。
结语
通过推理奖励函数,模型在微调过程中表现出了可靠的性能和一致的结果。你可以探索完整的实现代码,并亲自尝试。源代码已经开源,可以在 GitHub 上找到。
参考
https://github.com/yai333/Text-to-SQL-GRPO-Fine-tuning-Pipeline/tree/main
本文转载自Halo咯咯 作者:基咯咯
