资讯动态

构建 OpenAssistant 影视剧台词对话语料:tv_dialogue 数据集从抓取到统一格式化的完整工程实践

发布时间:2026/9/19 22:23:23 来源:尧图企业网站定制
构建 OpenAssistant 影视剧台词对话语料tv_dialogue 数据集从抓取到统一格式化的完整工程实践【免费下载链接】Open-AssistantOpenAssistant is a chat-based assistant that understands tasks, can interact with third-party systems, and retrieve information dynamically to do so.项目地址: https://gitcode.com/gh_mirrors/op/Open-Assistant影视剧字幕与剧本中蕴含着海量自然、口语化、多角色轮转的对话文本是训练对话式 AI 的重要语料来源。本文以 OpenAssistant 仓库中的 tv_dialogue 数据集为研究对象完整讲解其设计动机、统一的数据格式规范、覆盖 9 类影视作品/电影的来源构成以及从公开渠道下载、清洗、结构化、导出 Parquet 的全套可复现代码流程读者学完后即可按同样方法构建属于自己的多来源对话数据集。该数据集位于仓库 data/datasets/tv_dialogue包含 README.md数据卡片、两个 Jupyter Notebookpublic.ipynb 处理 Friends、The Office、Marvel、Doctor Who、Star Trek 五个纯对话来源imsdb.ipynb 负责从 imsdb.com 抓取带详细场景描述的完整剧本以及 requirements.txt 依赖清单。一、数据集定位为什么要为对话模型收集影视台词对话数据集通常来自三大渠道社交平台用户发言、机器生成对话、以及影视剧本/字幕。前两者或噪音较多或缺乏多轮对话的自然结构。影视剧本则天然具备以下优势多角色轮转结构每句台词带明确的说话人标注天然形成[说话人] 台词的交替结构是训练多轮对话模型的理想输入口语化表达密度高剧本语言贴近真实交流包含大量省略、停顿、语气词有助于模型学习自然语言节奏场景上下文丰富台词依附于具体场景场景切换、画外音v.o.等标注为理解对话语境提供了辅助信息来源公开可获取本数据集的全部剧本均来自公开的 GitHub 仓库、Kaggle 数据集和剧本网站工程上可复现。正因如此tv_dialogue 将影视剧对话/剧本作为对话语料的一个独立来源按照 OpenAssistant 的语料组织方式每条样本即一集/一部电影进行统一整理。二、数据集规模与 YAML 数据卡片解读数据卡片头部dataset_info块从 HuggingFace Datasets 的视角声明了数据集的 Schema是理解整个数据集结构的第一份官方文档dataset_info: features: - name: TEXT dtype: string - name: METADATA dtype: string - name: SOURCE dtype: string splits: - name: train num_bytes: 211728118 num_examples: 2781 download_size: 125187885 dataset_size: 211728118 license: mit task_categories: - conversational - text2text-generation language: - en tags: - OpenAssistant - transcripts - subtitles - television pretty_name: TV and Movie dialogue and transcript corpus size_categories: - 1Kn10K要点拆解字段值含义featuresTEXT / METADATA / SOURCE每条样本三个字段均为字符串splits.train2781 条 / 211,728,118 字节单个 train 划分数据集约 2.1 亿字节download_size125,187,885 字节原始文件压缩下载体积约 1.25 亿字节licensemitMIT 开源协议task_categoriesconversational, text2text-generation对话与文本生成两类任务均可使用languageen当前仅收录英语语料size_categories1Kn10K样本量在 1000 到 10000 之间三个特征列的分工明确TEXT是经过统一格式化后的完整剧本正文METADATA是该集/该片的结构化信息JSON 字符串SOURCE则记录原始出处格式为来源组织/抓取者如friends/emorynlp保证每条语料可溯源。三、统一数据格式一集一行[说话人] 台词README 中给出了格式规范的官方示例[PERSON 1] Hello [PERSON 2] Hello Person 2! Hows it going? (they are both talking) [PERSON 1] I like being an example on Huggingface! They are examples on Huggingface. CUT OUT TO ANOTHER SCENCE We are somewhere else [PERSON 1 (v.o)] I wonder where we are?从示例可以归纳出这条数据集的格式化约定角色标注每句对白以[说话人]前缀开始多行台词同一说话人的连续多行台词在下一个[前持续累积如[PERSON 2]的两行内容场景信息以原文保留如(they are both talking)这样的动作提示、CUT OUT TO ANOTHER SCENCE这样的场景切换说明作为场景上下文留在文本中而非被粗暴删除特殊说话人标记[PERSON 1 (v.o)]中的(v.o)表示画外音voice-over说明该台词属于非画面内的画外叙述每行一条样本数据集以一集 / 一部电影为一行共 2781 行而不是以单句对白为行——这样每条样本天然是一段完整、有开头结尾的多轮对话。值得注意的是这种粗粒度一行的设计与后续 OpenAssistant 的训练数据组织方式一致先以完整剧本为单位组织语料再在训练阶段由数据加载器按需要切分成对话片段。仓库中的相关加载逻辑可参考 data/datasets/init.py 等数据集入口文件。四、语料来源全景两类剧本、九大出处README 将全部来源分成两类并附上了原始出处链接本文按仓库文档整理如下原始链接见 README 原文此处保留来源标识供追溯4.1 纯对话类仅保留台词附带少量场景信息剧集剧本数抓取来源Source 标识Friends236 集character-mining 项目emorynlpfriends/emorynlpThe Office186 集Kaggle 数据集 nasirkhalid24office/nasirkhalid24Marvel Cinematic Universe18 部电影Kaggle 数据集 pduntonmarvel/pduntonDoctor Who306 集Kaggle 数据集 jeanmidevdrwho/jeanmidevStar Trek708 集chakoteya.net基于 Star_Trek_Scripts 项目整理startrek/chakoteya这一类的特点是原始数据本身已具备结构化字段说话人、季、集、场景加工重点是合并字段、过滤噪音、按集聚合。4.2 完整剧本类带详细场景描述作品剧本数抓取来源Source 标识Top Movies919 部电影imsdb.comimsdbTop Movies171 部电影dailyscript.comdailyscriptStargate SG-118 集imsdb.comimsdbSouth Park129 集imsdb.comimsdbKnight Rider80 集knightriderarchives.comknightriderarchives这一类的特点是原始材料是非结构化的纯文本剧本含大量场景描述、动作指示加工重点是编写解析器从 HTML/DOM 中提取对白、识别说话人、清理脏文本。两类来源在产出阶段最终都会落入完全相同的TEXT / METADATA / SOURCE三列格式。五、工程实现一public.ipynb——结构化数据集的下载与聚合public.ipynb 面向数据本身已结构化的五个来源核心流程为下载 → 读取为 DataFrame → 逐集聚合 → 统一三列 → 导出 Parquet。5.1 环境准备与依赖仓库提供了 requirements.txt内容如下beautifulsoup4 kaggle numpy pandas pyarrow requests tqdm在 Colab 中运行时Notebook 顶部预留了设置脚本git clone 仓库后进入本目录、pip install -r requirements.txt。其中kaggle库用于下载 Kaggle 数据集使用前需要先在账户页面获取kaggle.json凭据Notebook 代码注释中已说明。5.2 FriendsTSV 读取 场景分隔 过滤噪音Friends 数据来自 emorynlp/character-mining 项目的friends_transcripts.tsv制表符分隔读取后得到 67373 行、每行包含season_id / episode_id / scene_id / utterance_id / speaker / tokens / transcript的语料表覆盖 S01~S10 全部 236 集。关键加工步骤对应 Notebook 代码friends[group] friends[[season_id, episode_id]].apply( lambda x: f{x[0]}_{x[1]}, axis1 )构造 group 键把season_id episode_id拼成s01_e01形式的分组键作为一集的粒度季/集与标题映射Notebook 内硬编码了全 10 季的剧名表episodes[season][episode] - title用于把结构化 ID 还原为可读剧名逐集聚合与文本拼接核心循环如下行号对应 public.ipynbdata {TEXT: [], METADATA: [], SOURCE: []} for name, group in tqdm(friends.groupby(group)): metadata { show: Friends, season: group[season_id].values[0], episode: group[episode_id].values[0], title: episodes[group[season_id].values[0]][group[episode_id].values[0]], } text, last_scene fFriends - {metadata[title]}\r\n\r\n, None group.sort_values(by[scene_id, utterance], ascendingTrue, inplaceTrue) for index, row in group.iterrows(): if last_scene is None: last_scene row[scene_id] elif last_scene ! row[scene_id]: last_scene row[scene_id] text \r\n---------------------------------------\r\n\r\n if row[speaker] unknown or row[tokens] [] or pd.isna(row[transcript]): continue text f[{row[speaker].strip()}] {row[transcript].strip()}\r\n data[TEXT].append(text) data[METADATA].append(json.dumps(metadata)) data[SOURCE].append(friends/emorynlp) data pd.DataFrame(data)这段代码体现了整个数据集格式规范的三个核心约定文本头Friends - {title}作为该集的标题行接下来空两行开始正文场景分隔符检测到scene_id变化时插入---------------------------------------分隔线对应 README 示例中的场景切换语义噪音过滤说话人为unknown、tokens 为空[]、台词缺失NaN三种情况直接跳过保证产出文本的干净度。最终样本形如Friends - The Pilot [Monica Geller] Theres nothing to tell! Hes just some guy I work with! [Joey Tribbiani] Cmon, youre going out with the guy! ...METADATA 为{show: Friends, season: s01, episode: e01, title: The Pilot}的 JSON 字符串SOURCE 为friends/emorynlp。5.3 The Office / Marvel / Doctor WhoKaggle 数据集下载与字段映射这三个来源统一走 Kaggle APIkaggle.api.dataset_download_files(nasirkhalid24/the-office-us-complete-dialoguetranscript, office, unzipTrue) kaggle.api.dataset_download_files(pdunton/marvel-cinematic-universe-dialogue, marvel, unzipTrue) kaggle.api.dataset_download_files(jeanmidev/doctor-who, drwho, unzipTrue)The Office读取office/The-Office-Lines-V4.csv54626 行字段season / episode / title / scene / speaker / line去掉多余的Unnamed: 6列同样用season_episode拼 group 键按s01/e01的零填充格式写入 METADATAfs{str(x).zfill(2)}最终 186 集Marvel18 部电影的对话台词行含(Rhodes is telling the same story...)这类括号场景说明保留在文本中METADATA 含电影标题等信息Doctor Who按episodeid分组306 集METADATA 额外记录季、集、集名且文本头会带上播出方式和博士代数的信息Doctor Who ({diffusion}; {doctors}) - {title}体现元信息融入正文的灵活性。三者的共同收尾动作data.to_parquet(office.pq, row_group_size100, enginepyarrow, indexFalse)即以 100 行为一个 row group、使用 pyarrow 引擎导出 Parquet——这也是 README 数据卡片中download_size与dataset_size体积差异的来源之一Parquet 的列式压缩特性。5.4 Star TrekJSON 抓取与多剧集合Star Trek 部分通过requests.get直接抓取all_scripts_raw.json708 集覆盖 DS9、ENT 等子系列逐条解析为TEXT / METADATA / SOURCE三列public.ipynbMETADATA 记录{show: Star Trek, season: DS9, episode: ...}等字段最后导出picard.pq。六、工程实现二imsdb.ipynb——非结构化剧本的爬虫解析imsdb.ipynb 面向 imsdb.com 等纯文本剧本网站数据没有结构化字段必须先写解析器。Notebook 定义了IMSDbCrawler类核心方法如下方法职责_get(url, allow_unicode_errors)带容错地请求 HTML 页面get_catalog()从 imsdb.com 抓取剧本目录剧名 链接导出 CSV 状态文件download(url)下载单个剧本页面_clean_dom(html)清洗 HTML DOM去掉脚本、样式等无关节点is_person(speaker)判断一行文本是否为说话人标注用于区分台词与场景描述parse(html)解析剧本正文提取[说话人] 台词结构save(url)组合 download parse成功则写入本地.txt文件6.1 清洗与说话人识别_clean_dom负责把网页还原为接近纯文本的剧本剥离script、style等节点后通过正则与启发式规则判断哪些行是[说话人]开头。is_person从源码结构看是后续parse阶段区分说话人行与场景描述行的关键判定函数。6.2 剧本解析与脏数据过滤parse阶段的处理要点对应 imsdb.ipynb对 HTML 实体做反转义如amp;→统一换行符\r\n与\n归一化多个连续空行压缩为两个质量门控若解析结果中没有出现连续的[说话人] 台词交替模式正则\[.?\] .?\r\n\r\n\[.?\] .?\r\n\r\n说明该页不是有效剧本直接返回空串丢弃画外音等特殊标注文本内保留了[Person (v.o)]等括号注记作为场景信息的一部分save方法额外以解析后长度小于 128 字符作为阈值过滤掉过短的无效页面。6.3 全量抓取与断点续爬Notebook 主体展示了带断点续爬能力的批处理循环imsdb.ipynbcatalog pd.read_csv(STATUS) crawled catalog.copy() for index, row in catalog.iterrows(): if pd.isna(row[status]): t time.time() print(f{row[alpha]} {row[title]}, end ) if ic.save(row[link]): print(✔️, end ) crawled.at[index, status] 1.0 else: print(❌, end ) crawled.at[index, status] 0.0 print(f- {(time.time() - t):.3f}s) crawled.to_csv(STATUS, indexFalse) if pd.notna(crawled[status]).sum() % 25 0: print( f▶▶▶ {pd.notna(crawled[status]).sum()} done f({int(crawled[status].sum())} successful) out of {len(crawled)} ◀◀◀ ) print(Done.)设计要点状态落盘每抓一部就写回 CSV 状态文件中断后重跑时通过pd.isna(row[status])自动跳过已完成条目进度反馈逐条打印耗时秒每完成 25 条打印一次累计统计成功数 / 总数结果保存save方法把剧本以{剧名}.txt写入FOLDER目录文件名由 URL 清洗得到非字母数字字符替换为-/_。这份脚本同时覆盖了 README 中Top Movies (imsdb / dailyscript)、Stargate SG-1、South Park、Knight Rider等来源的抓取基础设施。全部文本抓取完成后再按与 public.ipynb 相同的三列格式聚合、导出汇入最终数据集。七、在 OpenAssistant 中的使用方式与复现路径7.1 本地复现# 进入数据集目录仓库根目录相对路径 cd data/datasets/tv_dialogue pip install -r requirements.txt随后按需执行两个 Notebook先运行 public.ipynb 处理五个结构化来源需要 Kaggle API 凭据kaggle.json再运行 imsdb.ipynb 抓取剧本网站耗时长依赖断点续爬机制。7.2 数据加载示例数据集以 HuggingFace Datasets 的dataset_info格式描述训练侧可参考仓库的 HuggingFace 数据集导出工具 backend/oasst_backend/utils/hugging_face.py 与 backend/export.py 了解 OpenAssistant 如何将这类对话语料转换为 HuggingFace 格式模型训练侧的对话数据加载可参考 model/model_training/custom_datasets/oasst_dataset.py。7.3 注意事项来源授权数据集以 MIT 协议发布但各原始剧本来源的版权情况请以各来源网站为准使用时注意区分公开可抓取与可自由商用语言范围当前仅英语language: en如需多语言需自行扩展数据源文本噪声部分剧本源尤其完整剧本类仍可能残留格式噪声训练前可结合数据清洗脚本进一步过滤。八、总结tv_dialogue 是 OpenAssistant 中一个典型的多来源、单格式数据集工程5 个结构化来源 4 类非结构化剧本来源最终统一为TEXT / METADATA / SOURCE三列的 2781 行语料。其工程价值不止于数据本身更在于沉淀了一套可复用的方法论——结构化数据用 pandas 聚合、非结构化数据用爬虫 正则解析、全程以 Parquet 落地、元数据以 JSON 字符串随行存储、来源标识保证可溯源。这套下载 → 清洗 → 统一格式化 → 导出的流水线可以直接迁移到任何其他影视对话语料的构建任务中。如需继续深入推荐阅读同一目录下的两个 Notebook 原文以及 data/datasets 下其他数据集的 README了解 OpenAssistant 对不同语料来源的差异化处理策略。【免费下载链接】Open-AssistantOpenAssistant is a chat-based assistant that understands tasks, can interact with third-party systems, and retrieve information dynamically to do so.项目地址: https://gitcode.com/gh_mirrors/op/Open-Assistant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价