语法工程(Grammar Engineering)和大型语言模型(LLM)这两个方向,过去几年大部分时间是被分开讨论的:一边是手工构建形式语法、追求可解释性和规则覆盖度,另一边是端到端学习、追求规模和数据驱动的效果。这篇题为How Useful are LLMs for Grammar Engineering? Cantonese ParGram Resources and Controlled Experimental Evaluation with English Baselines的研究,恰好把两者拉到了同一个实验台前:LLM 到底能不能帮语法工程师把活干得快一点、质量高一点?它并不是又一个“LLM 自动生成代码”的演示,而是把粤语这种资源相对稀疏的语言作为目标,在 ParGram 这一国际协同语法工程框架下,用英语基线做了一次受控评估。
如果你关心的是“LLM 能不能直接帮我写语法规则、生成语料、做语言标注”,这篇论文的实验设计非常值得拆解。我在这篇文章里会把它改写成一套可落地的工程思路:如何用 LLM 批量生成粤语测试句子、如何辅助编写词条与句法规则草稿、如何做受控对比评估并和英语基线对齐、如何控制 token 成本和输出稳定性。整个流程不需要专用硬件,用云端 API 或本地小模型都能跑,适合做语言学研究、NLP 数据集构建和形式语法资源积累的读者参考。
1. 核心能力速览
从研究标题和实验设计来看,这不是一个拿来即用的工具包,而是一套“LLM + 语法工程”的方法论。它的能力边界主要体现在这些地方:
| 能力项 | 说明 |
|---|---|
| 研究对象 | LLM 对语法工程工作的辅助价值,包括测试句子生成、词条建议、规则草稿、错误分析 |
| 语法框架 | ParGram(Parallel Grammar Project),基于词汇功能语法(LFG)的多语言语法开发范式 |
| 目标语言 | 粤语,资源相对稀疏、口语与书面语差异明显,适合检验 LLM 能否弥补数据不足 |
| 基线设计 | 英语基线用于对照,判断 LLM 的效果是语言无关的通用能力,还是仅对部分语言有效 |
| 评估方式 | 受控实验,通过对比 LLM 生成结果与专家结果,或对比不同模型配置的输出来度量帮助程度 |
| 硬件需求 | 不固定;云端 API 无需本地 GPU,若使用本地开源模型则需要按模型大小配置显存和内存 |
| 是否支持 API | 可选;实验脚本可通过 OpenAI 兼容接口接入云端模型或本地推理服务 |
| 是否支持批量任务 | 支持;核心工作量之一就是批量生成、批量清洗、批量判断 |
| 适合人群 | 计算语言学研究者、NLP 工程师、语法资源建设者、粤语语料开发者 |
从材料来看,这项研究最值得关注的不是某个单一模型跑分,而是它把语法工程拆成了几个可以被 LLM 介入的环节,并给出了相对严谨的验证方式。后面几章的实验方案,就是按照这个思路展开的。
2. 研究背景与问题定位
2.1 语法工程到底难在哪
语法工程的目标是把语言知识写成机器可读的形式规则,让计算机能够分析句子结构。以 LFG 为例,一个句子会被同时表示成 c-structure(短语结构)和 f-structure(功能结构),前者描述“词怎么排”,后者描述“谁是谁的主语、谁是谁的宾语、时态是什么”。ParGram 联盟已经为英语、日语、法语、德语等语言开发了可运行的语法,但每一种新语言都要从头积累词汇、形态规则、短语结构规则和语义映射规则。
这项工作有三个痛点:
第一,规则覆盖度需要大量测试句子。每写一条规则,就要想清楚哪些句型应该接受、哪些应该拒绝,测试句子少则几百,多则几千。
第二,词条信息不全。粤语这类语言,助词、语气词、话题标记非常丰富,词典和语法书覆盖有限,人工补充成本高。
第三,错误分析极度耗时。语法分析器在跑语料时会产生大量错误,需要逐个句子判断是规则缺失、词条缺失还是标注错误。
2.2 LLM 可以在哪些环节介入
LLM 擅长从少量示例中生成大量表面形式不同的句子,也能根据指令输出结构化结果。把这两个能力放到语法工程里,正好对应上面三个痛点:
- 批量生成测试句子:给定句式模板,让 LLM 生成合法、自然、结构可控的粤语例句。
- 生成词条草稿:给定单词和例名,让 LLM 补全词类、论元结构、搭配限制等候选信息。
- 规则调试建议:给定失败句和当前规则描述,让 LLM 提出可能缺失的规则或词条。
- 错误分类:把解析器错误按“词条缺失”“规则缺失”“语料噪声”等类别做初筛。
但这里有一个关键问题:LLM 生成的句子可能不自然,也可能包含幻觉,它的语法判断并不等于人工专家判断。所以研究里才要有受控实验和基线,否则很容易被“看起来能跑”的输出误导。
2.3 为什么选粤语和英语做对比
粤语在形式语法资源建设上属于“高挑战、低资源”的语言:口语和书面语差异大,句末助词、话题结构、量词系统都有明显特点,现有树库和语法规则不多。把粤语作为实验对象,能更好地观察 LLM 在数据不足时是否仍然有用。
英语作为基线则提供一个“天花板参照”:英语语法资源已经很成熟,人工编写测试句子经验充足,LLM 在英语上的辅助效果可以视为方法有效性的上界。如果 LLM 在英语上也帮不上忙,那说明问题出在方法本身;如果英语有效但粤语无效,则可能是语言资源或提示词设计的问题。
3. 方法论拆解:受控实验、粤语资源与英语基线
3.1 受控实验的核心思路
受控实验的关键在于“控制变量”。在语法工程场景里,需要控制的变量包括:
- 任务内容:所有语言使用相同类型的任务,比如生成“主谓宾”句、生成“话题句”、补全词条。
- 输入信息:给 LLM 的提示词结构保持一致,只替换语言名称和示例。
- 评估标准:判断句子是否合法、是否属于目标结构,必须使用同一套规则和同级别的专家评审。
- 基线设置:英语作为熟悉语言,粤语作为目标语言,两边独立执行再对比。
如果缺少这些控制,LLM 在一种语言上表现好,可能只是因为提示词里包含了更多隐式信息,而不是模型真正掌握了语法结构。
3.2 评估对象是什么
评估对象不是单个句子,而是“LLM 辅助产物是否被语法工程师采纳”。可以用下面的逻辑链路表示:
- 给定一个句式描述,比如“粤语话题句”。
- LLM 生成 N 个候选句子。
- 专家或语法分析器对候选句子做判断。
- 统计接受率、结构覆盖率、错误类型。
- 与英语基线的结果对比,得到“有用性”结论。
这套链路可以重复执行多次,也可以切换不同模型、不同提示词、不同采样温度来观察影响。
3.3 实验需要的物料
在开始部署实验之前,至少要准备以下资源:
- 句式清单:粤语和英语各一组,覆盖主谓、谓宾、话题、句末助词、被动、量词等结构。
- 种子例句:每个句式提供 2 到 3 个专家确认过的正确答案,作为 LLM 的 few-shot 示例。
- 评估标准:包含“合法”“不合法但可修复”“完全不可用”等层级。
- 语法分析器或人工评审:如果没有可运行的 LFG 语法,可以先以人工评审为准,后续再接入分析器。
这些物料单独准备会花不少时间,但它们是受控实验的基础,不能跳过。
4. 实验环境准备与评估工具搭建
先讲结论:这套实验不需要重型本地环境。用云端大模型 API 最省事,用本地小模型也可以,只是输出质量和速度会有差异。
4.1 基础依赖
推荐使用 Python 3.10 或更高版本,安装以下库:
pip install requests openai pandas pydantic如果你要接本地推理服务,还有一个更轻的方案:先启动一个兼容 OpenAI 接口的本地服务,再用openai库调用。这样脚本逻辑在云端和本地之间切换时,只需要改base_url和model两个字段。
4.2 模型选择建议
- 如果追求生成质量和格式稳定性,优先选择支持结构化输出或 JSON mode 的商业模型,例如 GPT-4o、Claude 3.5 Sonnet、Qwen-Max 等。
- 如果必须在本地处理敏感语料,或者不想把粤语句子送到外部 API,可以使用 Qwen2.5 7B/14B、DeepSeek-V3 等开源模型,通过 vLLM 或 Ollama 启动。
- 做第一轮快速验证时,建议先用小模型或便宜模型跑通提示词,再把验证过的提示词放到大模型上批量执行。
4.3 统一调用封装
先封装一个统一的 LLM 调用函数,后续所有实验都复用它:
import os from openai import OpenAI client = OpenAI( api_key=os.getenv("LLM_API_KEY", "EMPTY"), base_url=os.getenv("LLM_BASE_URL", "http://127.0.0.1:8000/v1"), ) def chat_completion(prompt, model="Qwen/Qwen2.5-7B-Instruct", temperature=0.2, max_tokens=1024): response = client.chat.completions.create( model=model, messages=[{"role": "user", "content": prompt}], temperature=temperature, max_tokens=max_tokens, ) return response.choices[0].message.content注意:base_url默认指向本地 vLLM 服务端口;如果使用云端服务,需要改成对应厂商的地址,并设置好LLM_API_KEY。
4.4 输出规范设计
LLM 输出格式不稳定,是实际使用中最常见的问题。建议在提示词里明确要求结构化输出,并在应用层做解析兜底。
下面是一个通用的 JSON 输出示例:
{ "sentences": [ { "sentence": "佢食咗苹果。", "structure": "SVO", "naturalness": 4 } ] }解析时不要只依赖json.loads,要加上异常处理和重试机制,避免一条坏格式输出中断整个批量任务。
5. 实验一:LLM 生成粤语语法测试句
5.1 测试目的
验证 LLM 是否能为粤语语法规则生成结构正确、表达自然的测试句子,并统计不同句式下的接受率。
5.2 提示词模板
以“句末助词”为例,种子例句可以写成:
请根据以下句式生成 10 个合法的粤语句子。 句式:陈述句 + 句末助词“啦”,表示语气变化或事件实现。 示例: 1. 我走啦。 2. 佢食完饭啦。 要求: - 只输出 JSON 数组,不要输出多余说明。 - 句子必须自然,符合母语者习惯。 - 避免抄袭示例,结构可以相同但内容要不同。 - 用传统汉字书写。5.3 批量生成脚本
写一个可复用的批量脚本,读取句式配置,调用 LLM,保存结果:
import json, time from pathlib import Path def load_config(path): with open(path, "r", encoding="utf-8") as f: return json.load(f) def run_batch(config_path, output_path): configs = load_config(config_path) results = [] for cfg in configs: prompt = build_prompt(cfg) content = chat_completion(prompt, temperature=0.4) parsed = parse_json(content) # 需要实现健壮的解析 for item in parsed: item["target_structure"] = cfg["name"] item["language"] = cfg["language"] results.extend(parsed) time.sleep(0.5) # 避免请求过密 Path(output_path).write_text( json.dumps(results, ensure_ascii=False, indent=2), encoding="utf-8" )5.4 判断成功的标准
一条生成句是否合格,可以从三个维度看:
- 结构匹配:句子是否真正包含目标句式,比如句末是否有“啦”并且语气符合例句。
- 语法合法:句子是否符合粤语语法,母语者是否会说。
- 内容多样性:是否大量复制示例内容,主语、动词、宾语是否重复。
建议在正式评估前先做一轮小样本人工评审,确定当前提示词能产出多少合格句子。如果接受率过低,优先调整种子例句数量和提示词表达。
6. 实验二:LLM 辅助词条与规则开发
6.1 测试目的
测试 LLM 是否能把日常粤语句子中的词条信息抽取成 LFG 所需的词条草稿,减少人工录入成本。
6.2 输入输出设计
以动词“食”为例,输入可以是:
请根据粤语句子“佢食咗苹果。”,为动词“食”生成一个 LFG 风格词条草稿。 输出 JSON: { "word": "食", "category": "V", "predicate": "食<SUBJ, OBJ>", "tense_feature": "PERF", "note": "普通话对应‘吃’" }这里的重点是“草稿”,不要求一步到位。LLM 生成的词类、论元结构、特征值都需要语法工程师复核。实际工程中,可以把生成结果导出成表格,逐条确认后导入语法词典。
6.3 规则调试场景
当语法分析器处理某个句子失败时,可以把错误句子、当前规则名称、已有词条片段一起发给 LLM:
句子:佢好靓。 分析结果:失败。 当前规则:NP 内部一致性检查失败。 请指出可能原因,并给出 2 个修复建议。这个场景的价值在于,LLM 可以快速给出候选假设,缩小工程师排查范围。但要注意,LLM 不一定真正理解 LFG 的规则机制,它生成的是“基于文本模式的可能原因”,不能替代人工推理。
6.4 批量词条候选生成
与实验一类似,可以批量处理一个词汇表:
words = ["食", "饮", "行", "讲", "听", "睇", "走", "坐", "买", "卖"] for word in words: prompt = f"请为粤语动词‘{word}’生成一个 LFG 风格词条草稿,返回 JSON。" output = chat_completion(prompt) print(word, output)建议对每个词尝试 2 到 3 次,选取最稳定的输出,或者多次输出后做投票,减少随机性带来的偏差。
7. 实验三:受控对比评估与结果解读
7.1 评估流程
受控实验的核心是“同一套流程,换语言”。比如先定义一个句式集合:
| 句式编号 | 句式名称 | 英语示例 | 粤语示例 |
|---|---|---|---|
| S1 | 主谓宾 | She ate an apple. | 佢食咗苹果。 |
| S2 | 话题句 | This book, I have read. | 呢本书,我睇过。 |
| S3 | 被动句 | The window was broken. | 只窗被人打烂。 |
| S4 | 句末助词 | (无明显对应) | 我走啦。 |
每个句式分别让 LLM 生成,然后由同一批评审者按同一标准打分。这样得到的差异才能归因于语言本身或提示词设计。
7.2 指标计算
最简单也最可解释的指标是“候选句接受率”。可以写一个函数:
def compute_acceptance(results): accepted = sum(1 for r in results if r["accepted"] == True) return accepted / len(results) if results else 0 english_acceptance = compute_acceptance(english_results) cantonese_acceptance = compute_acceptance(cantonese_results) print(f"English acceptance: {english_acceptance:.2f}") print(f"Cantonese acceptance: {cantonese_acceptance:.2f}")除了接受率,还可以统计:
- 结构覆盖率:目标句式中有多少比例至少生成了一个合格候选句。
- 失败原因分布:把不合格句分为“结构错误”“词汇错误”“不自然”三类,观察哪类问题占比高。
- 人工修复成本:评审者修改一条不合格句子平均需要的字数或时间。
这些指标不依赖特定模型,适合复现不同实验设置。
7.3 从结果反推提示词设计
如果英语接受率远高于粤语,先不要急着下结论说“LLM 对粤语不好”。更合理的排查顺序是:
- 粤语种子例句是否足够准确?如果种子例句本身不自然,LLM 会放大这种不自然。
- 是否需要加入“传统汉字”“口语化程度”等额外约束?
- 模型是否见过足够多粤语数据?换一个参数更大的模型,结果可能完全不同。
- 是否因为英语提示词更容易构建?如果有差异,要把提示词长度、示例数量对齐。
受控实验的价值就在于此:它逼着你去解释“为什么有差异”,而不是只看最终分数。
8. 资源成本、稳定性与排查清单
8.1 Token 消耗与成本控制
批量生成句子和词条看起来不复杂,但实际跑下来 token 消耗比你想象的要高。每条提示词中的示例、指令、历史消息都会占用上下文,而请求频率过高还可能导致 API 限流。
几个控制成本的实用做法:
- 每次请求只做一件事:生成句子就只生成句子,不要同时要求词条和规则建议。
- 压缩种子例句数量:每个句式保留 2 到 3 个种子例句足够,不必一次塞 10 个。
- 打开缓存:对相同句式配置的请求做本地缓存,避免重复调用。
- 设置
max_tokens上限:防止模型在 JSON 后面追加大量无关解释。 - 先用小模型调试提示词,定稿后再用大模型批量跑。
8.2 显存与本地推理
如果使用本地开源模型,显存需求取决于模型大小。按常见经验,7B 模型在 16GB 显存下勉强可跑,14B 或更大模型建议 24GB 以上。但这不是本研究的硬性要求,因为云端 API 完全可以完成实验。对资源有限的研究者,我更推荐第一阶段全部用云端 API,跑通流程后再考虑本地部署。
8.3 常见问题与排查方法
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| LLM 返回大量非 JSON 文本 | 提示词约束不明确 | 查看原始输出样例 | 强制要求“只输出 JSON”,增加解析兜底 |
| 生成的粤语句子不自然 | 种子例句质量差或模型语料覆盖不足 | 人工评审一轮 | 增加地道种例句,降低 temperature |
| 调用 API 频繁超限 | 请求并发过高 | 查看服务端返回码 | 增加 sleep,使用指数退避重试 |
| 同一提示词结果不稳定 | 采样温度过高 | 对比多次输出 | 将 temperature 调低至 0.2 以下 |
| 批量任务中途崩溃 | 单条输出异常未被捕获 | 加日志并观察中断位置 | 增加 try/except,失败后写入错误日志 |
| 本地模型显存不足 | 模型超出可用显存 | 使用 nvidia-smi 查看 | 换更小模型或启用量化 |
| 粤语例句被误判为普通话 | 提示词没有明确汉字和口语风格 | 检查句子表现 | 增加“传统汉字”“粤语口语”约束 |
| 英语基线表现异常 | 提示词设计不一致 | 对比两边提示词格式 | 确保任务结构、示例数量完全对齐 |
9. 最佳实践、合规边界与下一步
9.1 推荐工作流
如果你要把这篇论文的方法落地,我建议按下面顺序走:
- 先用英语跑通 5 到 10 个句式的生成、评估、指标计算流程。
- 建立粤语句式清单,请粤语母语者确认种子例句。
- 用小模型做提示词调试,输出合格率稳定后切换大模型。
- 每个句式生成 20 到 50 条候选句,组织人工评审。
- 对不合格句做错误分类,决定是否把“修复规则”也接入 LLM 辅助流程。
- 保留所有提示词、模型版本、温度参数、评审记录,方便后续复现。
这套流程把 LLM 当作“生产候选材料的人”,而不是“最终决策者”,更适合语法工程这种要求高可解释性的场景。
9.2 需要坚持的边界
使用 LLM 生成粤语语料和语法规则时,有几个边界必须守住:
- 涉及真实人物、真实语音、私人对话的语料,未经授权不得用于实验。
- 从书籍、网页、社交平台采集语料时,必须遵守版权规定,优先使用授权语料和公开验证集。
- LLM 可能生成带有地域偏见或冒犯性的例句,正式发布前必须人工复核。
- 如果使用商业 API,不要把未脱敏的隐私文本直接传入提示词。
- 语法规则、词条信息若来自已有词典或语法书,需要在论文或项目中标注来源,避免学术不端。
9.3 下一步可以继续做什么
这个方向的后续空间很大。比较实际的做法包括:
- 把评估维度扩展到粤语特有的句末助词系统、话题结构、量词、动补结构。
- 对比多个 LLM 在粤语语法工程上的效果,不只是看接受率,还要看错误类型分布。
- 把 LLM 生成的候选词条接入可运行的 LFG 语法,做端到端解析验证。
- 构建一个小规模“粤语语法工程测试集”,公开给其他研究者复用。
从这篇论文的定位看,它最值得学习的不是某个具体 prompt,而是“如何验证 LLM 的辅助价值”。在语法工程这种以人工知识为核心的工作流里,LLM 不可能完全替代语法工程师,但它可以让工程师把精力从重复造句、补词条、分错误,转移到真正需要判断力的规则设计上。先把英语基线跑通,再把粤语放进去,这一步比追求“多 fancy 的模型”更实在。