CoT 推理帮助模型逐步解释其思维,从而提高文本到 SQL 生成的准确性和可解释性。本文探讨如何将标准 7b 参数 LLM (Qwen2.5-Coder-7B-Instruct) 转换为使用 GRPO 为文本到 SQL 任务提供结构化推理的 LLM。重点在于设计有效的奖励函数,以鼓励模型正确推理并生成准确的 SQL。
为什么 GRPO 非常适合文本到 SQL
你可能已经熟悉 GRPO(引导式奖励策略优化)——这是 DeepSeek 引入的一种强化学习技术,用于训练其 R1 推理模型。在其众多用例中,Text-to-SQL 非常适合基于 GRPO 的微调。原因如下:
推理至关重要
SQL 不仅仅是语法,更是结构化逻辑。GRPO 鼓励模型解释为什么选择某些表、连接或过滤器,从而训练它们像人类分析师一样“思考”,并更紧密地贴合用户意图。
它可以捕获静默错误
无需推理,即使问题是“上个月的活跃用户”,模型也可能会返回 SELECT * FROM users。GRPO 的双奖励系统(推理 + SQL)有助于及早发现这些细微的不匹配。
小型模型需要护栏
小型模型(例如 7B)通常难以处理复杂的逻辑。GRPO 就像训练轮一样:它奖励循序渐进的思维,惩罚不合逻辑的输出,即使 SQL 看起来没问题。
通过透明度建立信任
如果一个模型写道:“我使用了‘购买’表,因为问题询问的是销售额”,那么调试和验证就会变得容易得多。GRPO 将这种清晰度融入到训练循环中。
但要达到这个目的,奖励设计变得至关重要
文本到 SQL 推理的挑战在于创建有效的奖励函数,以评估解释的质量和生成的 SQL 的准确性。
设计基于推理的微调奖励函数
为了在文本到 SQL 的生成中实现结构化推理,我创建了多部分奖励函数,每个函数都捕获了模型行为的一个关键方面。这些奖励函数用于使用Unsloth框架对 7B 模型进行微调。
每个函数在塑造模型的推理能力和SQL准确性方面发挥着不同的作用,总体工作流程如下:
soft_format_reward_func(权重:1.0)
简单函数检查完成是否与软模式匹配:<reasoning>(.*?)</reasoning>\s*<sql>(.*?)</sql>
如果匹配则返回完整format奖励权重(默认 1.0),否则返回 0。
complexity_reward(权重:0.6)
这确保 SQL 复杂性与黄金 SQL(答案)一致,避免过度复杂或不够复杂。
不含黄金的 SQL:
使用黄金 SQL,reward = exp(-0.5 * (log(ratio))²) * complexity_weight
按权重缩放complexity(默认值 0.6)
推理质量奖励(权重:0.7)
该奖励函数使用一组旨在反映类似人类的分析思维的启发式方法来评估模型产生的推理部分的质量。
reward = min(1.0, sum(component_scores)) * reasoning_weight
各部分得分:
最终奖励按权重缩放reasoning(默认 0.7)
execute_query_reward_func(权重:1.2)
基于执行的评估,执行奖励是最重要的。它测试生成的 SQL 是否真正起作用并产生正确的结果:
基本奖励:0.1 *sql_correctness_weight如果语句类型匹配
对于 SELECT 语句:
对于 DML 语句(INSERT、UPDATE、DELETE):
错误处理:
所有奖励均按权重缩放sql_correctness(默认 1.2)
在 GRPO 训练期间,这些奖励函数会同时指导模型:
这种平衡的方法确保模型既能发展强大的推理能力,又能提高 SQL 准确性,而不是针对单一维度的性能进行优化。
GRPO培训中的实施
以下是使用 Unsloth 通过 GRPO 训练器设置这些奖励函数的方法:
from trl import GRPOConfig, GRPOTrainer
# Configure training
training_args = GRPOConfig(
use_vllm = True,
learning_rate = 5e-6,
per_device_train_batch_size = 1,
gradient_accumulation_steps = 1,
num_generations = 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()
并且系统提示应该明确指示模型使用推理:
You are an AI assistant that converts natural language questions into SQL queries.
Given a database schema and a question, generate the correct SQL query.
Respond ONLY in the following format, including the <reasoning> and <sql> tags:
<reasoning>
Think step by step to understand the database schema and the question.
Identify the necessary tables, columns, joins, and conditions.
Explain the logic for constructing the SQL query.
</reasoning>
<sql>
-- Your SQL query here
</sql>
评估奖励制度的有效性
为了评估我们的多维奖励函数的有效性,我利用 LLM-as-a-Judge 来评估经过微调的模型的 SQL 正确性和推理质量。
使用GPT-4o-mini作为专家评判者对经过微调的 Qwen2.5-Coder-7B-Instruct 模型进行了评估:
评估维度:四个关键方面,按 1-5 的等级进行评分:
评估提示:
As an SQL expert, evaluate this text-to-SQL conversion. Score each dimension from 1-5 (1=poor, 5=excellent).
DATABASE SCHEMA:
{sample['sql_context']}
QUESTION:
{sample['sql_prompt']}
GOLD SQL (CORRECT):
{sample['sql']}
MODEL OUTPUT:
{sample['model_output']}
Provide scores in this exact format:
SQL_SCORE: [1-5] - Does the SQL work and produce correct results?
REASONING_SCORE: [1-5] - Is the reasoning clear, logical, and references correct schema?
FORMAT_SCORE: [1-5] - Does it follow <reasoning>...</reasoning><sql>...</sql> format?
EDUCATIONAL_SCORE: [1-5] - Would this help someone learn SQL?
OVERALL_SCORE: [average]
EXPLANATION: [brief explanation of strengths/weaknesses]
ERROR_TYPE: [none/syntax/logic/format/other]
结果
经过 250 个步骤、仅使用 300 个示例进行训练的微调模型取得了可靠的评估结果:
该模型展现出强大的整体性能,SQL 生成准确率高(44/5,得分 4 或 5),推理质量优异(48/50,得分 4 或 5),格式遵循近乎完美(49/50,得分 5),且具有明确的教育价值。总体而言,88% 的输出得分达到 4.0 或更高,反映出其一致性、结构良好且可解释的结果。
结论
我创建的推理奖励函数性能可靠,并在微调过程中产生了一致的结果。