question_generation

GitHub
1.1k 350 中等 2 次阅读 3周前MIT开发框架语言模型
AI 解读 由 AI 自动生成,仅供参考

Question Generation是一个基于Transformer的问答生成工具,专注于从文本段落中自动生成问题。它通过预训练的序列到序列模型(如T5)实现端到端的问答生成,支持多种输入处理方式,包括答案前置格式和答案高亮格式。该工具解决了传统问答生成任务中模型复杂、依赖人工处理流程的问题,提供简化的数据处理和训练脚本,让研究者能快速验证不同生成策略。适用于需要构建问答系统、知识蒸馏或文本理解应用的开发者和研究人员,尤其适合希望基于预训练模型进行微调的场景。技术上采用预训练Transformer架构,支持答案感知和无答案监督的生成模式,并通过不同的输入编码方式提升生成质量,为问答生成研究提供了灵活且易用的实验平台。

使用场景

某在线教育平台开发团队需为新发布的《Python编程入门》教材自动生成配套练习题,以提升学生互动学习体验。

没有 question_generation 时

    • 人工编写问题耗时2-3小时/章节,严重拖慢课程更新节奏
    • 问题质量依赖教师经验,常出现与上下文脱节或难度失衡(如基础概念题混入高级算法题)
    • 扩展至新教材时,需临时抽调3名教研员,团队资源紧张
    • 无法根据学生答题数据动态优化问题库,反馈周期长达1-2周

使用 question_generation 后

    • 问题生成时间压缩至5分钟/章节,支持批量处理整本教材
    • 生成的问题精准匹配教材上下文(如自动识别"Guido van Rossum"等关键实体生成相关问题)
    • 新教材上线后立即自动生成配套题库,无需额外人力投入
    • 实时分析学生答题数据,自动优化问题难度分布

question_generation 通过端到端Transformer模型,将教材问题生成效率提升60倍,同时确保问题质量与教学目标高度一致。

运行环境要求

操作系统
  • 未说明
GPU

未说明

内存

未说明

依赖
notes首次运行需下载约5GB模型文件,建议使用conda管理环境
python未说明
transformers==3.0.0
nltk
nlp==0.2.0
question_generation hero image

快速开始

使用 🤗transformers 进行问题生成

项目详情

问题生成是从一段文本中自动生成问题的任务。最直接的方法是基于答案的问题生成。在这种方法中,模型会接收答案和段落,并根据段落上下文为该答案生成一个问题。尽管关于问题生成任务已有许多研究论文,但它仍然不如问答任务那样主流。原因之一是早期的大多数研究都采用了复杂的模型或处理流程,且没有现成的预训练模型可用。近年来,一些论文,特别是 UniLM 和 ProphetNet,提供了 SOTA 的预训练权重用于问题生成,但其使用方式似乎相当复杂。

本项目旨在通过开源的方式,利用预训练的 Transformer 模型(特别是序列到序列模型),以简单直观的端到端方法进行问题生成研究,避免复杂的流水线。目标是提供简化的数据处理和训练脚本,以及易于使用的推理流程。

初步实验

初步实验使用 SQuADv1 数据集和 T5 模型进行,输入处理格式如下面所述。

基于答案的问题生成

对于基于答案的模型,输入文本可以有两种处理方式。

1. 前缀格式:

在这种格式中,答案直接添加到上下文之前,并用分隔符 token 分隔。例如:

42 [SEP] 42 是生命、宇宙以及一切的答案。

对于 T5 模型,输入会被处理成这样:

answer: 42 context: 42 是生命、宇宙以及一切的答案。

2. 高亮格式

在这种格式中,答案片段会在文本中用特殊的高亮 token 标记出来。

《hl》 42 《hl》 是生命、宇宙以及一切的答案。

这一想法在“一种基于循环 BERT 的问题生成模型”论文中提出。参见第 4.3 节。

答案抽取模型

由于基于答案的模型需要答案才能生成问题,因此我们需要一个能够从文本中提取答案片段的模型。这可以通过多种方法实现,比如命名实体识别、名词短语抽取等。但在这里,我们训练了一个专门用于提取答案片段的模型,以观察其效果。对于 T5 模型,答案抽取是通过文本到格式转换来完成的。

由于高亮格式需要知道提取出的答案片段的位置,因此答案抽取的输入处理如下:

  1. 将文本按句子分割。
  2. 对于包含答案的句子,用 <hl> token 高亮标记该句子。
  3. 对于目标文本,将该句子中的所有答案用 <sep> token 连接起来。

例如,对于以下文本:

Python 是一种编程语言。由 Guido van Rossum 创建,于 1991 年首次发布。

将会生成如下示例:

输入文本: 《hl》 Python 是一种编程语言。《hl》 由 Guido van Rossum 创建,于 1991 年首次发布。

目标文本: Python <sep>

以及

输入文本: Python 是一种编程语言。《hl》 由 Guido van Rossum 创建,于 1991 年首次发布《hl》。

目标文本: Guido van Rossum <sep> 1991 <sep>

在推理时,文本会被分割成句子,并对每个句子进行高亮标记。

多任务问答-问题生成

对于基于答案的问题生成,通常需要三个模型:第一个模型用于提取答案片段,第二个模型根据答案生成问题,第三个模型则是问答模型,它会接收问题并给出答案。然后我们可以比较这两个答案,以判断生成的问题是否正确。

为一个任务同时使用三个模型会带来很大的复杂性,因此我们的目标是创建一个多任务模型,使其能够同时完成以下三项任务:

  1. 提取答案片段
  2. 根据答案生成问题
  3. 问答

T5 模型通过使用论文中描述的任务前缀,以多任务方式进行了微调。

端到端问题生成(无需答案监督)

在端到端问题生成中,模型被要求在不提供答案的情况下生成问题。这篇论文更详细地讨论了这一思路。在这里,T5 模型被训练为仅根据上下文同时生成多个问题,问题之间用 <sep> token 分隔。以下是示例的处理方式:

输入文本:Python 是一种编程语言。由 Guido van Rossum 创建,于 1991 年首次发布。

目标文本:谁创造了 Python?<sep> Python 是什么时候发布的?<sep>

所有训练细节都可以在 这个 wandb 项目中找到

结果

使用上述方法在 SQuAD1.0 验证集上的结果。解码时采用束搜索,束宽为 4,最大解码长度设为 32。

对于多任务问答-问题生成模型,EM 和 F1 分数分别以 QA-EM 和 QA-F1 的形式给出。

使用 nlg-eval 包来计算各项指标。

名称 BLEU-4 METEOR ROUGE-L QA-EM QA-F1 QG-FORMAT
t5-base-qg-hl 21.3226 27.0854 43.5962 - - highlight
t5-base-qa-qg-hl 21.0141 26.9113 43.2484 82.46 90.272 highlight
t5-small-qa-qg-hl 18.9872 25.2217 40.7893 76.121 84.904 highlight
t5-small-qg-hl 18.5921 24.9915 40.1886 - - highlight
t5-small-qg-prepend 18.2791 24.6722 39.958 - - prepend

要求

transformers==3.0.0
nltk
nlp==0.2.0 # 仅在需要微调时使用。

安装 nltk 后,请执行以下命令:

python -m nltk.downloader punkt

使用方法

使用模仿 🤗transformers 流水线的管道,以便于推理。

该管道分为 3 个任务:

  1. question-generation:用于单任务问题生成模型。
  2. multitask-qa-qg:用于多任务问答和问题生成模型。
  3. e2e-qg:用于端到端问题生成。

在 Colab 中打开

问题生成

from pipelines import pipeline

nlp = pipeline("question-generation")
nlp("42 是生命、宇宙以及一切的答案。")
=> [{'answer': '42', 'question': '生命、宇宙以及一切的答案是什么?'}]

prepend 格式

nlp = pipeline("question-generation", model="valhalla/t5-small-qg-prepend", qg_format="prepend")
nlp("42 是生命、宇宙以及一切的答案。")
=> [{'answer': '42 ', 'question': '生命、宇宙以及一切的答案是什么?'}]

多任务问答-问题生成

nlp = pipeline("multitask-qa-qg")

# 要生成问题,只需传递文本即可
nlp("42 是生命、宇宙以及一切的答案。")
=> [{'answer': '42', 'question': '生命、宇宙以及一切的答案是什么?'}]

# 对于问答任务,传递包含 "question" 和 "context" 的字典
nlp({
    "question": "42 是什么?",
    "context": "42 是生命、宇宙以及一切的答案。"
})
=> '生命、宇宙以及一切的答案'

端到端问题生成(无需答案监督)

nlp = pipeline("e2e-qg")
nlp("Python 是一种编程语言。由 Guido van Rossum 创建,于 1991 年首次发布。")
=> [
    '什么是编程语言?',
    '谁创建了 Python?',
    'Python 是何时首次发布的?'
]

默认情况下,两个管道都会使用 t5-small* 模型。若要使用其他模型,可通过 model 参数指定路径。

默认情况下,question-generation 管道会下载 valhalla/t5-small-qg-hl 模型,并采用 highlight 问题生成格式。如果希望使用 prepend 格式,则需提供 prepend 模型的路径,并将 qg_format 设置为 "prepend"。对于提取答案跨度的任务,它会使用 valhalla/t5-small-qa-qg-hl 模型;您可以通过 ans_model 参数指定不同的模型。

multitask-qa-qg 模型适用于能够同时提取答案跨度、进行问题生成和问答的多任务模型,因此不需要单独的 ans_model。默认情况下,使用的是 valhalla/t5-small-qa-qg-hl 模型,并采用 highlight 格式。如果希望使用 prepend 格式,则需提供 prepend 模型的路径,并将 qg_format 设置为 "prepend"

e2e-qg 管道用于端到端问题生成。这些模型可以在没有答案监督的情况下同时生成多个问题。默认情况下,它使用 valhalla/t5-small-e2e-qg 模型。

微调

数据处理

为了支持不同的数据格式,训练器期望使用预处理过的缓存数据集,这样你可以按照自己的方式处理数据。缓存的数据集应该使用 torch.save 保存,并且在 __getitem__ 方法中返回一个包含 source_idstarget_idsattention_mask 键的字典。

  • source_ids: 编码后的源文本
  • target_ids: 编码后的目标文本
  • attention_mask: source_ids 的注意力掩码

T2TDataCollator 负责准备正确的 input_idslabels。它还会动态裁剪批次以去除多余的填充标记,从而加快训练速度。

data/squad_multitask 目录下包含了经过修改的 SQuAD 数据集,用于答案感知型问题生成(同时使用 prepend 和 highlight 格式)、问答(文本到文本)、答案抽取以及端到端的问题生成。这个数据集可以使用优秀的 🤗nlp 库加载,这使得数据处理变得非常容易。

要处理并缓存数据集,请使用 prepare_data.py 脚本。它会根据 model_type 参数加载正确的分词器。该脚本会在分词器中添加两个新标记 <sep><hl>, 并将其保存到 {model_type}_qg_tokenizer 路径。你应该将此分词器传递给微调脚本。

数据集将被保存在 data/ 目录下。你需要通过 train_file_namevalid_file_name 参数提供文件名。

为单任务问题生成处理数据,使用 highlight_qg_format 格式

python prepare_data.py \
    --task qg \
    --model_type t5 \
    --dataset_path data/squad_multitask/ \
    --qg_format highlight_qg_format \
    --max_source_length 512 \
    --max_target_length 32 \
    --train_file_name train_data_qg_hl_t5.pt \
    --valid_file_name valid_data_qg_hl_t5.pt \

为多任务 qa-qg 处理数据,使用 highlight_qg_format 格式

valid_for_qg_only 参数用于决定验证集是否只包含 qg 任务的数据。在我的多任务实验中,我使用了仅包含 qg 任务的验证数据,以便于将评估损失曲线与其他单任务模型进行比较。

python prepare_data.py \
    --task multi \
    --valid_for_qg_only \ 
    --model_type t5 \
    --dataset_path data/squad_multitask/ \
    --qg_format highlight_qg_format \
    --max_source_length 512 \
    --max_target_length 32 \
    --train_file_name train_data_qa_qg_hl_t5.pt \
    --valid_file_name valid_data_qg_hl_t5.pt \

为端到端问题生成处理数据集

python prepare_data.py \
    --task e2e_qg \
    --valid_for_qg_only \ 
    --model_type t5 \
    --dataset_path data/squad_multitask/ \
    --qg_format highlight_qg_format \
    --max_source_length 512 \
    --max_target_length 32 \
    --train_file_name train_data_e2e_qg_t5.pt \
    --valid_file_name valid_data_e2e_qg_t5.pt \

训练

使用 run_qg.py 脚本来开始训练。它使用 transformers 的 Trainer 类来训练模型。

python run_qg.py \
    --model_name_or_path t5-small \
    --model_type t5 \
    --tokenizer_name_or_path t5_qg_tokenizer \
    --output_dir t5-small-qg-hl \
    --train_file_path data/train_data_qg_hl_t5.pt \
    --valid_file_path data/valid_data_qg_hl_t5.pt \
    --per_device_train_batch_size 32 \
    --per_device_eval_batch_size 32 \
    --gradient_accumulation_steps 8 \
    --learning_rate 1e-4 \
    --num_train_epochs 10 \
    --seed 42 \
    --do_train \
    --do_eval \
    --evaluate_during_training \
    --logging_steps 100

或者,如果你想从脚本或笔记本中直接训练,可以这样做:

from run_qg import run_qg

args_dict = {
    "model_name_or_path": "t5-small",
    "model_type": "t5",
    "tokenizer_name_or_path": "t5_qg_tokenizer",
    "output_dir": "t5-small-qg-hl",
    "train_file_path": "data/train_data_qg_hl_t5.pt",
    "valid_file_path": "data/valid_data_qg_hl_t5.pt",
    "per_device_train_batch_size": 32,
    "per_device_eval_batch_size": 32,
    "gradient_accumulation_steps": 8,
    "learning_rate": 1e-4,
    "num_train_epochs": 10,
    "seed": 42,
    "do_train": True,
    "do_eval": True,
    "evaluate_during_training": True,
    "logging_steps": 100
}

# 开始训练
run_qg(args_dict)

评估

使用 eval.py 脚本来评估模型。

python eval.py \
    --model_name_or_path t5-base-qg-hl \
    --valid_file_path valid_data_qg_hl_t5.pt \
    --model_type t5 \
    --num_beams 4 \
    --max_decoding_length 32 \
    --output_path hypothesis_t5-base-qg-hl.txt

这会将输出保存到 {output_path} 文件中。

要计算指标,安装 nlg-eval 包并运行:

nlg-eval --hypothesis=hypothesis_t5-base-qg-hl.txt --references=data/references.txt --no-skipthoughts --no-glove 

应用场景 🚀

  1. 一个关于你选择主题的简单知识问答游戏 -
    Medium 文章及其 Colab 笔记本
  2. Autocards,通过机器生成的抽认卡加速学习

相关论文

常见问题

相似工具推荐

stable-diffusion-webui

stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。

162.1k|★★★☆☆|今天
开发框架图像Agent

everything-claude-code

everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上

139k|★★☆☆☆|今天
开发框架Agent语言模型

ComfyUI

ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。

107.7k|★★☆☆☆|2天前
开发框架图像Agent

NextChat

NextChat 是一款轻量且极速的 AI 助手,旨在为用户提供流畅、跨平台的大模型交互体验。它完美解决了用户在多设备间切换时难以保持对话连续性,以及面对众多 AI 模型不知如何统一管理的痛点。无论是日常办公、学习辅助还是创意激发,NextChat 都能让用户随时随地通过网页、iOS、Android、Windows、MacOS 或 Linux 端无缝接入智能服务。 这款工具非常适合普通用户、学生、职场人士以及需要私有化部署的企业团队使用。对于开发者而言,它也提供了便捷的自托管方案,支持一键部署到 Vercel 或 Zeabur 等平台。 NextChat 的核心亮点在于其广泛的模型兼容性,原生支持 Claude、DeepSeek、GPT-4 及 Gemini Pro 等主流大模型,让用户在一个界面即可自由切换不同 AI 能力。此外,它还率先支持 MCP(Model Context Protocol)协议,增强了上下文处理能力。针对企业用户,NextChat 提供专业版解决方案,具备品牌定制、细粒度权限控制、内部知识库整合及安全审计等功能,满足公司对数据隐私和个性化管理的高标准要求。

87.6k|★★☆☆☆|今天
开发框架语言模型

ML-For-Beginners

ML-For-Beginners 是由微软推出的一套系统化机器学习入门课程,旨在帮助零基础用户轻松掌握经典机器学习知识。这套课程将学习路径规划为 12 周,包含 26 节精炼课程和 52 道配套测验,内容涵盖从基础概念到实际应用的完整流程,有效解决了初学者面对庞大知识体系时无从下手、缺乏结构化指导的痛点。 无论是希望转型的开发者、需要补充算法背景的研究人员,还是对人工智能充满好奇的普通爱好者,都能从中受益。课程不仅提供了清晰的理论讲解,还强调动手实践,让用户在循序渐进中建立扎实的技能基础。其独特的亮点在于强大的多语言支持,通过自动化机制提供了包括简体中文在内的 50 多种语言版本,极大地降低了全球不同背景用户的学习门槛。此外,项目采用开源协作模式,社区活跃且内容持续更新,确保学习者能获取前沿且准确的技术资讯。如果你正寻找一条清晰、友好且专业的机器学习入门之路,ML-For-Beginners 将是理想的起点。

85k|★★☆☆☆|今天
图像数据工具视频

ragflow

RAGFlow 是一款领先的开源检索增强生成(RAG)引擎,旨在为大语言模型构建更精准、可靠的上下文层。它巧妙地将前沿的 RAG 技术与智能体(Agent)能力相结合,不仅支持从各类文档中高效提取知识,还能让模型基于这些知识进行逻辑推理和任务执行。 在大模型应用中,幻觉问题和知识滞后是常见痛点。RAGFlow 通过深度解析复杂文档结构(如表格、图表及混合排版),显著提升了信息检索的准确度,从而有效减少模型“胡编乱造”的现象,确保回答既有据可依又具备时效性。其内置的智能体机制更进一步,使系统不仅能回答问题,还能自主规划步骤解决复杂问题。 这款工具特别适合开发者、企业技术团队以及 AI 研究人员使用。无论是希望快速搭建私有知识库问答系统,还是致力于探索大模型在垂直领域落地的创新者,都能从中受益。RAGFlow 提供了可视化的工作流编排界面和灵活的 API 接口,既降低了非算法背景用户的上手门槛,也满足了专业开发者对系统深度定制的需求。作为基于 Apache 2.0 协议开源的项目,它正成为连接通用大模型与行业专有知识之间的重要桥梁。

77.1k|★★★☆☆|昨天
Agent图像开发框架