尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

GPT-2 输出文本格式化:三步把生成结果改造成 JSON、Markdown 与纯文本

GPT-2 输出文本格式化:三步把生成结果改造成 JSON、Markdown 与纯文本 GPT-2 输出文本格式化三步把生成结果改造成 JSON、Markdown 与纯文本【免费下载链接】gpt-2Code for the paper Language Models are Unsupervised Multitask Learners项目地址: https://gitcode.com/GitHub_Trending/gp/gpt-2深夜十一点运营同事给你连发三条消息AI 写作工具跑出来的文字我复制进公众号排版全乱了能给我 Markdown 吗数据库那边要存一批说要 JSON 格式。还有日志里只要纯文本别整花里胡哨的。GPT-2 这个开源项目在生成文本上很能打可它交到你手里的永远是一段没有结构的字符串。文本生成完了然后呢存到哪、给谁看、怎么被下游系统消费——这些事它一概不管。这篇文章不搞理论轰炸而是带你走一遍真实的改代码路径先写一个能导出 JSON 的函数再扩展出纯文本和 Markdown最后处理批量生成时的文件写入问题。每一步都有能立刻运行的代码你照着敲就行。动手之前先把仓库准备好git clone https://gitcode.com/GitHub_Trending/gp/gpt-2 cd gpt-2 pip install -r requirements.txt # 注意项目基于 TensorFlow 1.x一、先别急着写代码格式化就是转换插头你出国旅行时见过转换插头吧电脑本身只有一个 USB-C 口到了不同国家你只需要换一个插头适配器电脑不用动照样充电。这里的格式化本质上是同一件事。GPT-2 的生成链路很短encoder.encode()把提示词变成 token →sample.sample_sequence()采样出新 token →encoder.decode()还原成字符串。结果到手的text就是你电脑的 USB-C 口。而 JSON、Markdown、纯文本分别是三个国家的插座。你要做的只是给这个text加一个插头适配器让它能被不同场景接收。 关键认知格式转换发生在生成之后发生在你的 Python 代码里跟模型本身没有任何关系。这意味着——想加任何新格式都不用重新训练模型。明白了这个前提代码就好写多了我们只需要一个适配器的通用接口让每种格式各自实现自己的转换逻辑。二、第一版一个函数就能导出 JSON先不搞复杂设计。你只需要一个能跑的函数拿到正反馈再说。JSON 导出的最小实现长这样import json import datetime def to_json(text, **meta): 最朴素的 JSON 导出文本 附加字段 payload {text: text, **meta} return json.dumps(payload, ensure_asciiFalse, indent2) meta {sample_id: 1, timestamp: datetime.datetime.now().isoformat()} print(to_json(这是模型生成的一段文字, **meta))运行效果{ text: 这是模型生成的一段文字, sample_id: 1, timestamp: 2026-08-13T16:09:57.123456 }注意两个细节都是新手常踩的ensure_asciiFalse不写的话中文会全部变成\u4eba\u5de5这样的转义序列人没法读下游也不好处理。元数据用**meta传sample_id、时间戳、temperature 这些信息打包进 JSON之后做数据分析、查样本时全靠它们。✅ 小结你已经有了一条文本 → JSON的流水线可以把任何一次生成的文字变成结构化数据。三、第二版三种格式共用一个接口现在问题是如果每个格式都写一个函数调用方要写一堆if output_format json分支越加越乱。解决办法是抽出统一接口让调用方只认一个render()方法。在src/下新建formatters.pyimport json import re import datetime def base_meta(generated, prompt, model_name, temperature, top_k): 公共元数据所有格式都会用到 return { sample_id: generated, prompt: prompt, timestamp: datetime.datetime.now().isoformat(), model_name: model_name, temperature: temperature, top_k: top_k, } class Formatter: 统一接口每种格式一个子类只实现 render() def render(self, text, meta): raise NotImplementedError class PlainText(Formatter): def render(self, text, meta): return text class JsonText(Formatter): def render(self, text, meta): return json.dumps({text: text, **meta}, ensure_asciiFalse, indent2) class MarkdownText(Formatter): def render(self, text, meta): lines [# meta.get(title, GPT-2 生成文本), ] for para in re.split(r\n\s*\n, text.strip()): lines.append(re.sub(r\s, , para)) # 段落内压缩空白 lines [, ## 生成信息] lines [f- **{k}**: {v} for k, v in meta.items()] return \n\n.join(lines) FORMATTERS {text: PlainText, json: JsonText, markdown: MarkdownText} def get_formatter(name): 按名字取格式器不认识的名字直接报错避免静默出错 return FORMATTERS[name]()这段代码做了三件事统一了render(text, meta)接口用字典当注册表加新格式只需要往里塞一个类Markdown 格式里顺手做了段落折叠把换行和多余空格压平输出的文档更干净。接下来把它接进交互式生成脚本。原项目src/interactive_conditional_samples.py用的是 fire 库新参数直接写进函数签名即可def interact_model( model_name124M, nsamples1, batch_size1, temperature1, top_k0, output_formattext, # 新增text / json / markdown output_fileNone, # 新增输出文件路径 ): # ……原有加载模型、建图、恢复参数的代码不变…… fmt get_formatter(output_format) # 拿到插头适配器 while True: raw_text input(Model prompt ) context_tokens enc.encode(raw_text) generated 0 for _ in range(nsamples // batch_size): out sess.run(output, feed_dict{ context: [context_tokens for _ in range(batch_size)] })[:, len(context_tokens):] for i in range(batch_size): generated 1 text enc.decode(out[i]) block fmt.render(text, base_meta( generated, raw_text, model_name, temperature, top_k)) print( * 30 f SAMPLE {generated} * 30) print(block)改动只有三行加两个参数、创建fmt、把print(text)换成print(block)。现在你可以这样用python src/interactive_conditional_samples.py --model_name124M \ --output_formatmarkdown --temperature0.8 --top_k40生成结果会直接变成带标题、带段落、带生成信息区块的 Markdown 文本。 小结你的脚本现在已经支持三种输出格式切换格式只需要改一个命令行参数业务代码一行没多写。四、第三版批量生成时文件写入要格外小心交互式是边聊边生成批量脚本src/generate_unconditional_samples.py则是无人值守地连续产出。这时候最头疼的是文件写入。先说一个最常见的翻车现场有人用追加模式边生成边拼字符串写着写着 JSON 文件就变成{...}{...}{...}或者末尾多一个逗号整个文件解析失败。我的建议是先收集、后落盘——生成循环只负责往内存列表里塞结果循环结束统一写文件一次写成一个合法结构def save_outputs(blocks, output_file, output_format): JSON 一次写成一个合法数组其他格式用分隔线分隔 if not output_file: return if output_format json: with open(output_file, w, encodingutf-8) as f: json.dump([json.loads(b) for b in blocks], f, ensure_asciiFalse, indent2) else: with open(output_file, a, encodingutf-8) as f: f.write(\n\n---\n\n.join(blocks) \n)在批量脚本里接上blocks [] 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]) meta base_meta(generated, , model_name, temperature, top_k) blocks.append(fmt.render(text, meta)) print( * 30 f SAMPLE {generated} * 30) print(blocks[-1]) save_outputs(blocks, output_file, output_format)跑一次批量导出python src/generate_unconditional_samples.py --model_name124M \ --nsamples10 --length500 --output_formatjson --output_filebatch.json⚠️ 一个前提要说清楚save_outputs的 JSON 分支要求生成次数是有限的。如果你把nsamples设成 0无限生成循环永远不结束文件永远写不出来。无限生成场景下改用JSON Lines——每行一条 JSON边生成边追加天然合法python src/generate_unconditional_samples.py --model_name124M \ --nsamples20 --output_formatmarkdown --output_fileblog.md 小结你的批量脚本已经能稳定导出成文件了JSON 文件一定是合法数组Markdown 和纯文本文件也能直接打开使用。五、三种格式怎么选以及让导出更稳的三个习惯格式没有好坏只有合不合适。这张表帮你快速决策格式谁在看强项弱项典型去处JSON程序字段齐全、机器好解析人读着累数据库、API 响应、训练集纯文本人任何编辑器都能打开毫无结构日志、笔记、快速预览Markdown人排版工具结构清晰、可直接发布依赖工具链支持公众号、博客、技术文档选型之外还有三个让导出更稳的小习惯建议直接抄走习惯一格式化失败时兜底。模型输出的文本千奇百怪极端字符可能让某个格式器抛异常。包一层try/except失败就退回纯文本同时写一条日志try: block fmt.render(text, meta) except Exception as e: print(f[格式化失败] sample {generated}: {e}) block text # 兜底退回纯文本习惯二批量导出攒内存别在循环里反复 open 文件。每次循环都打开、写入、关闭文件I/O 开销会拖慢生成速度。上文save_outputs的做法就是循环内只 append 到列表循环外一次性写盘。习惯三日志文件单独记。把格式转换失败的样本编号、出错信息和前 100 个字符记到一个format_errors.log排查问题的时候不用翻完整输出。六、你可能会踩的坑FAQ 与常见误区Q导出的 JSON 里中文全是\u4eba\u5de5这种怎么办Ajson.dumps()里加ensure_asciiFalse这是最常见的第一个坑。QJSON 文件打开总报非法逗号或额外数据为什么A多半是边生成边用追加模式拼字符串。改成收集完一次写入JSON 数组或每行一条JSON Lines。Q加了--output_format参数fire 却报未知参数Afire 只认函数签名里的参数。新参数必须写进def interact_model(...)的签名缺了这个它根本不知道这个参数存在。Q想再加 CSV 或 HTML 格式改动量大吗A很小。写一个新类继承Formatter实现render()然后把它加进FORMATTERS字典——完了其他代码一行都不用动。Q为什么我改了 temperature输出却一模一样A检查是不是固定了seed。seed 固定时采样结果可复现这是它的功能不是 bug。想看到变化去掉 seed 参数。最后提醒一个新手最常有的误解别以为输出格式是模型的能力。模型只负责生成 token 序列格式化 100% 是生成之后、由你的 Python 代码完成的。想通这一层你就不会再为要不要为某个格式重新训练纠结了——永远不需要。从一段干巴巴的字符串到结构化的 JSON、可发布的 Markdown、随处可用的纯文本你只花了三步一个函数、一个接口、一次文件写入。下次运营同事再发消息来你可以从容地回一句要哪种格式现在就能导。【免费下载链接】gpt-2Code for the paper Language Models are Unsupervised Multitask Learners项目地址: https://gitcode.com/GitHub_Trending/gp/gpt-2创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表