
GPT-2输出进阶实战三步实现JSON/纯文本/Markdown多格式导出【免费下载链接】gpt-2Code for the paper Language Models are Unsupervised Multitask Learners项目地址: https://gitcode.com/GitHub_Trending/gp/gpt-2上周我用 GPT-2 给团队批量生成产品文案跑完interactive_conditional_samples.py后面对满屏的 SAMPLE 分隔线我发现自己居然要手动把几十段文本从终端里一段段复制出来、再逐个整理成运营能直接用的文档。那一刻我意识到GPT-2 生成文本的能力很强但输出这件事它真的没替我们想好。这篇文章就是为解决这个问题而写——通过给 GPT-2 增加多格式导出功能让生成结果从只能看变成可直接交付。你可能会问的三个问题动工之前先回答几个你可能最关心的问题它到底能做什么让interactive_conditional_samples.py和generate_unconditional_samples.py两个生成脚本支持把结果导出为 JSON、纯文本、Markdown 三种格式同时保留终端打印。上手难吗不难。不改动src/model.py、src/sample.py任何一行模型代码只新增一个格式化模块、给两个入口脚本各加两个参数全部改动约 150 行。和原版有什么区别原版只能print(text)后靠人肉复制改造后一句命令行就能把结果落盘成结构化文件还能自动附带样本编号、时间戳、模型参数等元数据。先说结论一套格式化输出层解决所有问题整个方案的思路很简单在生成流程的末端插入一个可插拔的格式化层文本从sample_sequence出来后先经过encoder.decode()还原成字符串再交给不同的Formatter加工最后既打印到终端、又按需写入文件。一句话概括生成逻辑不动输出逻辑重写。新增的src/formatter.py用策略模式组织每个格式一个类想加新格式只需再写一个类互不干扰。第一步新建 formatter.py把输出格式变成可插拔在src/目录下新建formatter.py定义基类、三种格式实现和一个工厂函数import json import re import datetime class OutputFormatter: 所有格式化器的基类子类必须实现 format() def format(self, text, metadataNone): raise NotImplementedError class PlainTextFormatter(OutputFormatter): def format(self, text, metadataNone): return text class JsonFormatter(OutputFormatter): def format(self, text, metadataNone): result { text: text, length: len(text), tokens: len(text.split()), } if metadata: result.update(metadata) return json.dumps(result, ensure_asciiFalse, indent2) class MarkdownFormatter(OutputFormatter): def format(self, text, metadataNone): md # GPT-2 Generated Text\n\n # 把空行分隔的段落重新整理压缩多余空白 paragraphs re.split(r\n\s*\n, text.strip()) md \n\n.join([ .join(p.split()) for p in paragraphs if p.strip()]) if metadata: md \n\n## 生成信息\n for k, v in metadata.items(): md f- **{k}**: {v}\n return md class FormatterFactory: staticmethod def get_formatter(format_type): if format_type json: return JsonFormatter() elif format_type markdown: return MarkdownFormatter() else: return PlainTextFormatter()设计上只做三件事基类定契约、子类管格式、工厂负责分发。JsonFormatter里用ensure_asciiFalse保证中文不被转义成\uXXXXMarkdownFormatter用正则把零散换行整理成规整段落——这两个细节后面避坑小节还会再提。第二步给交互式脚本加上输出格式与文件导出参数打开src/interactive_conditional_samples.py在interact_model的函数签名末尾追加两个参数然后在生成循环里插入格式化与写文件逻辑def interact_model( model_name124M, seedNone, nsamples1, batch_size1, lengthNone, temperature1, top_k0, top_p1, models_dirmodels, output_formattext, # 新增text / json / markdown output_fileNone, # 新增输出文件路径 ): # ... 原有模型加载代码保持不变 ... while True: raw_text input(Model prompt ) # ... 原有 encode 与 sess.run 逻辑保持不变 ... for i in range(batch_size): generated 1 text enc.decode(out[i]) formatter FormatterFactory.get_formatter(output_format) metadata { sample_id: generated, prompt: raw_text, timestamp: datetime.datetime.now().isoformat(), model_name: model_name, temperature: temperature, top_k: top_k, } formatted formatter.format(text, metadata) print( * 40 SAMPLE str(generated) * 40) print(formatted) if output_file: append_to_file(output_file, formatted, output_format)文件写入我单独抽了一个append_to_file函数重点是JSON 的追加写法。因为 JSON 是一整个数组的结构多次追加不能直接write()否则文件会变成非法 JSONdef append_to_file(path, content, fmt): with open(path, a, encodingutf-8) as f: if fmt json: if os.path.getsize(path) 0: f.write([\n) else: # 删除末尾的 ]补逗号再写新条目 with open(path, r, encodingutf-8) as rf: rf.seek(0, os.SEEK_END) rf.seek(rf.tell() - 1, os.SEEK_SET) rf.write(,\n) f open(path, a, encodingutf-8) f.write(content) f.write(\n]) else: f.write(\n * 40 SAMPLE \n) f.write(content) f.write(\n)JSON 这个先删尾巴再补逗号的写法是让多次追加后文件依然是一个合法 JSON 数组的关键值得单独记住。第三步让批量生成脚本也支持同样的参数src/generate_unconditional_samples.py的结构和交互版几乎一样照着同样的套路改即可。注意两点不同它没有prompt元数据里去掉该字段它支持nsamples0表示无限生成写文件时建议每满一批就 flush 一次避免程序中断时丢数据def sample_model( # ... 原有参数 ... output_formattext, output_fileNone, ): # ... 原有加载逻辑 ... generated 0 while nsamples 0 or generated nsamples: out sess.run(output) for i in range(batch_size): generated batch_size text enc.decode(out[i]) formatter FormatterFactory.get_formatter(output_format) metadata { sample_id: generated, timestamp: datetime.datetime.now().isoformat(), model_name: model_name, temperature: temperature, } formatted formatter.format(text, metadata) print( * 40 SAMPLE str(generated) * 40) print(formatted) if output_file: append_to_file(output_file, formatted, output_format)两个脚本都依赖fire.Fire()自动解析命令行参数所以新增的output_format、output_file不需要任何额外注册直接就能在命令行使用。第四步跑起来看效果环境准备如果还没下载模型# 克隆项目并安装依赖 git clone https://gitcode.com/GitHub_Trending/gp/gpt-2 cd gpt-2 pip install -r requirements.txt # 下载 124M 最小模型 python download_model.py 124M交互式生成JSON 格式落盘python src/interactive_conditional_samples.py \ --model_name124M \ --output_formatjson \ --output_fileresults.json批量生成一次产出 10 篇 Markdown 文档内容python src/generate_unconditional_samples.py \ --model_name124M \ --nsamples10 \ --length200 \ --output_formatmarkdown \ --output_filearticles.md最终results.json里的每条记录长这样{ text: 人工智能是计算机科学的一个分支致力于创造能够模拟人类智能的系统……, length: 856, tokens: 156, sample_id: 1, prompt: 什么是人工智能, timestamp: 2026-08-13T17:22:45.123456, model_name: 124M, temperature: 1.0, top_k: 0 }改造前后对比省下的不只是复制粘贴维度改造前改造后结果获取终端打印人肉复制自动落盘成文件数据形态纯文本无结构JSON 带元数据可直接入库批量产出每次手动整理一条命令产出 N 个样本二次加工需自己写解析交给程序即可消费可追溯性无记录时间戳、参数、编号齐全新增参数一览参数名类型默认值作用output_formatstringtext输出格式可选 text / json / markdownoutput_filestringNone输出文件路径不填则仅终端显示model_namestring124M模型大小可选 124M/355M/774M/1558Mtemperaturefloat1随机性控制越小越确定top_kinteger0采样候选词数量0 表示不限制top_pfloat1核采样概率阈值0 到 1 之间nsamplesinteger1/0样本数批量脚本中 0 表示无限生成lengthinteger由模型决定生成文本长度token 数避坑指南这些坑我替你先踩过了⚠️JSON 文件多次追加会变成非法文件。直接f.write()三次结果就是{...}{...}{...}任何解析器都会报错。必须用上面删尾补逗号的写法或者干脆改成每个样本存一个独立文件。⚠️中文变成\uXXXX转义。json.dumps默认会把非 ASCII 字符转义。写代码时务必带上ensure_asciiFalse否则中文全变成乱码一样的转义串。⚠️fire 参数名别用连字符。本项目用fire.Fire解析参数命令行里应使用下划线写法如--output_format而不是--output-format否则参数会被静默忽略。⚠️生成长度别超过模型窗口。length大于模型的n_ctx会直接抛错124M 模型窗口是 1024建议交互模式用默认值n_ctx // 2。小技巧想让 Markdown 里标题反映每次 prompt 的主题可以在metadata里加一个title字段MarkdownFormatter里用metadata.get(title, ...)兜底即可。举一反三还能怎么玩这个格式化层的设计决定了加格式极其廉价你完全可以按同样套路扩展CSV 格式继承OutputFormatter把文本里的逗号、换行转义后拼成一行方便导入 Excel 做统计分析。HTML 格式把段落包进p标签配合metadata生成一个可发布的静态页面。自定义模板给MarkdownFormatter增加template参数让用户自己定义标题层级和元数据排版。自动校验在写文件前对生成文本做空值、长度检查把异常样本单独记入format_errors.log避免污染主输出文件。流式落盘批量生成时用缓冲写入攒够 N 条再 flush配合大nsamples跑过夜任务也不怕中断。现在就去试试回头看这件事的本质是模型负责生成什么我们负责长什么样。一个不到 200 行的格式化层就让 GPT-2 从实验室玩具变成了能直接对接业务的数据源——无论是把结果喂给下游程序、整理成发布文档还是积累成微调用的训练语料都不再需要人肉搬运。下一步建议clone 项目后先跑一遍--output_formattext确认改动没破坏原有行为再切到 JSON 生成一批样本你会惊喜地发现——原来 GPT-2 的输出也可以这么听话。现在就打开终端试试吧。【免费下载链接】gpt-2Code for the paper Language Models are Unsupervised Multitask Learners项目地址: https://gitcode.com/GitHub_Trending/gp/gpt-2创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考