BERT问答长文本滑动窗口实现及squad_convert_example_to_features用法问询
滑动窗口QA处理 + Hugging Face Squad工具函数使用指南
一、先纠正下你对滑动窗口QA的理解
你对滑动窗口分割长文本的核心逻辑是对的:当输入文本超出模型最大序列长度时,通过max_len和stride把长文本切成重叠的小块,避免丢失上下文信息。
但有两个关键点需要补充:
- 有答案的问题不能只挑对应块训练:虽然第一个问题的答案在chunk1、第二个在chunk3,但实际训练时不能提前筛选块——一来模型需要学习从所有上下文里定位答案的能力,二来真实场景中你没法预判答案在哪块。正确做法是把问题和所有分割后的文本块组合输入,模型会自动找到包含答案的块并输出起止位置。
- 无答案问题的处理是对的:像"can pigs fly?"这种无答案的问题,必须和所有文本块组合输入,同时把答案起止索引设为-1,这样模型才能学习识别无答案的场景。
二、解决squad_convert_example_to_features的报错问题
你遇到的NameError完全是因为这个函数是内部辅助函数,它设计时没有支持传入tokenizer参数,默认会去找全局环境里的tokenizer变量——这也是你手动加全局tokenizer才能跑的原因。
官方推荐的是用批量处理的squad_convert_examples_to_features(就是你提到的带"s"的版本),这个是面向用户的正式API,支持传入tokenizer,用法更规范。修改后的代码如下:
from transformers.data.processors.squad import SquadV2Processor, squad_convert_examples_to_features from transformers import AutoTokenizer FILE_DIR = "." # 初始化tokenizer tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") processor = SquadV2Processor() # 获取训练集示例 examples = processor.get_train_examples(FILE_DIR) # 批量转换示例为模型可接受的特征 features, dataset = squad_convert_examples_to_features( examples=examples, tokenizer=tokenizer, # 这里可以直接传入tokenizer,不会报错 max_seq_length=384, doc_stride=128, max_query_length=64, is_training=True, return_dataset="pt" # 可选,返回PyTorch数据集,用TensorFlow的话改成"tf" )
如果你确实需要处理单个示例,也可以把tokenizer设为全局变量,再调用单个示例的函数:
# 先把tokenizer设为全局变量 tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") from transformers.data.processors.squad import squad_convert_example_to_features # 处理单个示例 example = examples[0] features = squad_convert_example_to_features( example=example, max_seq_length=384, doc_stride=128, max_query_length=64, is_training=True, )
总结
- 滑动窗口处理QA时,不管有没有答案,都要把问题和所有文本块组合输入;
- 优先使用官方提供的批量转换函数
squad_convert_examples_to_features,避免用单个示例的内部函数踩坑。
内容的提问来源于stack exchange,提问作者Benj
相关产品推荐
相关产品推荐

