简介:一份完整的 AI 自动写诗实验项目包,面向自然语言处理初学者或对生成式 AI 感兴趣的开发者。内含 Python 源码与编译文件、实验指导书、实验报告及演示 PPT,覆盖从诗歌数据集准备、模型训练到效果评估的完整链路,适合用来复现经典文本生成任务。
资源共 18 个文件,其中 4 个 py 和 6 个 pyc 是核心代码与缓存,配合 tang.npz 诗歌数据集和 log 训练日志可直接运行;两份 doc 文档分别提供实验步骤与结果分析,txt 数据文件用于预处理参考,PPT 则便于汇报展示。整个压缩包约 23.83MB,结构清晰,便于按需查阅。
目前已有 169 人学习下载。通过该包可以快速上手 LSTM、Transformer 等模型在古诗生成中的应用,理解 BLEU、ROUGE 等评估指标,并参考实验报告中的排错思路与调参记录,是兼顾理论与实践的自然语言处理学习素材。
1. 自动写诗.rar:先别急着解压,先看它解决什么问题
从网上下载一个“自动写诗.rar”,估计谁的第一反应都是双击解压、找README、然后运行脚本。我拿到这类压缩包项目,会先退一步问一句:里面这套“自动写诗”是怎么实现的?如果只是几个txt加一个模板脚本,半小时能跑通;如果带了模型权重和训练代码,那解压方式、运行环境、显存占用全都要重新评估。自动写诗本身不是玄学,是一个标准的序列生成任务——给定开头几个字,输出一首押韵且可控的诗。这篇文章就顺着rar包的解压、代码拆解、参数调优这条线,把这个标题变成你自己能复现、能改动的小项目。正在做NLP入门、创意写作工具或者期末项目的读者,可以直接按这条路径走。
2. 自动写诗的技术选型:从模板、N-gram到深度模型的取舍
2.1 自动写诗的本质是字符序列建模,不是随机拼词
无论是五言绝句还是七言律诗,写诗的过程都可以看作计算条件概率 p(x_t | x_1, x_2, ..., x_{t-1}),即给定前面已经出现的字,预测下一个字。它和普通文本生成最大的区别在于,诗有额外的约束:字数、平仄、押韵、对仗。所以自动写诗比一般的聊天机器人多两个评价维度——形式合规性和语义连贯性。形式不合规,生成结果再美也不能叫诗;语义不连贯,押韵再工整也是一堆无机词。
我拿到这类rar项目后的第一件事,不是急着跑生成脚本,而是先看里面是“成品”还是“半成品”。如果压缩包里有一个独立的exe或者编译好的可执行文件,那说明作者已经把整个流程固化,你只能当作黑匣子玩玩;如果里面有python脚本和txt语料,那才是能复现、能改参数的项目。自动写诗的方向本身没有太高门槛,门槛在于你能不能判断出包里那套实现用了什么技术栈。
2.2 三种常见实现路径:模板填充、N-gram统计、神经网络生成
先说规则模板。这种实现把诗句当成填空题:预定义好“平平仄仄平平仄,仄仄平平仄仄平”这类格律框架,再从韵脚库里选字填进去。它的优点是永远不会写出病句,连平仄都对齐;缺点是内容几乎谈不上“写”,形似而神无。如果你在rar里看到一堆JSON或Python字典结构,里面存的是韵脚表、意象词库,那基本就是这条路。这类代码适合做中古体打油诗玩具,不值得投入太多时间调参。
第二种是N-gram统计模型。它的思路是从大量语料中统计字与字之间的共现频率,形成一个一阶或多阶马尔可夫链。给定一个首字,从词频表里按概率选后继字。我在手机端小项目里用过这种方式,CPU就能跑,不需要GPU,压缩包里的代码往往也就几十行。但它有一个很明显的边界:一阶模型记不住远处的主语和谓语,生成四句以上的诗时,后半段经常断流。
第三种是神经网络生成,常见的是基于字符的LSTM或因果语言模型(GPT风格)。这类模型会把整句诗当作训练样本,学习“意象搭配”和“句式过渡”,生成质量明显高于前两种,但代价是你需要足够的语料和一定的训练环境。如果压缩包里带有训练脚本train.py和模型目录,那很可能走的是这条路。我的判断顺序是:先看有没有模型文件,再看有没有训练脚本,最后才看语料规模。
2.3 选型对照表:什么场景不配上Transformer
给你一张我做选型时常用的对照表,它能帮你快速判断“自动写诗.rar”里的代码到底值不值得深挖。
| 实现方式 | 训练成本 | 内存需求 | 生成质量 | 适合场景 |
|---|---|---|---|---|
| 规则模板 | 极低 | 忽略不计 | 形式稳、内容死 | 小程序玩具、固定话题打油诗 |
| N-gram | 低 | 低 | 短句通顺、长句断流 | 本地demo、课程设计 |
| 字符级LSTM | 中 | 中 | 风格稳、偶尔病句 | 创意工具原型、风格模仿 |
| GPT风格模型 | 高 | 高 | 高、但容易复读 | 云端产品、需要长文本控制的项目 |
有一个很重要的劝退点:如果你解压后数一下语料文本,只有几百首诗甚至几十条,就不要硬上Transformer。数据量不够时,深度学习模型学出来的不是诗,而是标点符号的分布规律,生成结果会出现大量的逗号句号堆叠,完全不像文本。我的原则是:语料少于5000行的,优先用N-gram或者LSTM;少于500行的,老老实实做模板。选型和语料量匹配,比盲目追新技术实用得多。
3. 把压缩包解压并跑通:从7-Zip命令到最小生成脚本
3.1 解压前先过问三件事:密码、编码、路径
rar格式不像zip那样被Windows资源管理器原生支持,所以“自动写诗.rar”双击后弹出“文件格式错误”是很常见的现象。这解释了一个高频问题:7zip可以解压rar文件吗?答案是完全可以。7-Zip内置了rar的解压支持,是Windows下最顺手的rar解压软件之一,需要注意它的创建功能不支持rar,但解压rar没有问题。
解压前有三件事我建议先确认。第一,这个rar包是否加了密码。用密码保护压缩包在论坛分享场景里太常见了,作者经常把密码写在下载页里,直接双击解压会提示“无加密”或“密码错误”。第二,编码问题。在Windows下打包的txt文件,默认编码很可能是GBK或GB18030,拿到Linux或macOS下解压后用UTF-8打开,中文诗会变成一堆乱码。第三,解压路径不要带空格和中文。路径里有空格会引出各种脚本参数解析问题,中文路径则会增加后续Python open文件时的编码工作量。
3.2 7-Zip命令行解压:用x参数,不要用e参数
很多人解压时随手敲7z e,这个命令会把归档里所有文件平铺到一个目录下,目录结构全丢。对于包含“data/”和“models/”子目录的自动写诗项目,平铺后代码相对路径全部失效,跑起来必翻车。我一般建议用7z x,x是extract with full paths,保留压缩包内目录结构。
7z x auto_poem.rar -o./poem -pYourPassword -y参数说明:x表示按完整路径解压;-o./poem指定输出目录,注意-o和目录名之间不能加空格;-pYourPassword是密码参数,如果没有密码就把整段-p去掉;-y表示遇到重名文件自动覆盖,适合反复解压排查场景。如果命令执行窗口反复报“Can not open encrypted file”,说明密码不对或者rar头带了加密标志,而不是文件损坏。
解压完成后不要急着双击运行。先检查一下文件结构,重点看有没有.bat、.sh、.exe这类可执行文件。从网上下载的压缩包项目来源不可控,尤其是带“破解版”“整合包”字样的rar,里面混入伪装脚本的概率不低。我曾见过一个自动写诗整合包,解压后有个“依赖安装.bat”,内容是下载一段powershell命令。有人跑完写成诗生成了,有人跑完电脑成了矿机。我的习惯是:所有可执行文件一律用文本编辑器打开看一遍,确认只是安装依赖或启动训练,再执行。
3.3 最小可运行的马尔可夫写诗脚本:验证包内环境
假设你在rar里只发现语料和README,没有现成的生成脚本。这时最快的路径是写一个最小的马尔可夫链生成器,先跑通,再决定要不要上深度学习。这个脚本不是为了替代包内代码,而是用来验证环境、验证数据是否完整。
import random import collections def build_markov(text): # 统计每个字的后继分布,key是当前字,value是后续字列表 model = collections.defaultdict(list) for line in text.split('\n'): line = line.strip() if len(line) < 5: continue for i in range(len(line) - 1): model[line[i]].append(line[i + 1]) return model def generate_poem(model, start_chars, length=20): # 指定开头几个字,长度为五言绝句的字数基准 result = list(start_chars) current = start_chars[-1] while len(result) < length: candidates = model.get(current) if not candidates: break current = random.choice(candidates) result.append(current) return ''.join(result) with open('poetry.txt', encoding='gb18030') as f: corpus = f.read() model = build_markov(corpus) print(generate_poem(model, '春'))这段代码的逻辑说明:build_markov用一个字典存储每个字所有可能的后续字。generate_poem从起始字开始做随机游走,每次从候选列表里随机挑一个后继字,形成一句连续文本。因为足够简单,它能帮你快速确认语料能不能被正常读取、段落结构是否完整、字符编码有没有问题。
这里有一个我踩过的坑:用encoding='utf-8'读一个Windows打包的gbk文本会直接报UnicodeDecodeError,但换成gb18030就顺畅了。gb18030的容错比gbk强,遇到一些生僻字不会随便崩。如果你发现生成的文本里有莫名其妙的单字重复,比如“春春风”,那不是脚本bug,是语料里每行首字和前一行的尾字被连到了一起。解决方法是切分时只按单句处理,不要把整首诗所有行连续拼接。
3.4 数据清洗决定模型上限:给训练脚本喂什么“诗”
如果你不满足于马尔可夫链,决定跑包里的深度学习训练脚本,那“数据准备”这一段比模型参数还重要。自动写诗模型输入的是字符序列,原始唐诗文本里夹杂着标题、作者、注释和空白符,这些噪声会让模型学到错误的转移关系。常见做法是用正则把非汉字字符全部过滤,只保留正文和必要的句读。
import re def clean_poem(raw_text): lines = [] for piece in raw_text.split('\n'): # 只保留汉字和中文标点,其余全部剔除 cleaned = re.sub(r'[^\u4e00-\u9fff,。]', '', piece) if len(cleaned) >= 20: lines.append(cleaned) return '\n'.join(lines)参数说明:正则里的\u4e00-\u9fff是汉字Unicode区域,它能把数字、英文字母、全角空格全部替换为空串。保留逗号和句号,是为了让模型学习诗句内部的停顿节奏。过滤规则中len(cleaned) >= 20表示只保留长度超过20的句子,这个阈值能去掉标题、作者行和不完整的句子。如果你的语料本身已经是干净的一行一首格式,这步可以跳过。
清洗完以后,我一般还会补一步长度规整:把每首诗按五言、七言分别存储,而不是混在一起。原因是五言和七言的节奏差异很大,混合训练容易生成出前五句五个字、后七句七个字的四不像。体裁分开训练或者至少在数据文件里加一个类型标记,能让生成端口的格式稳定性明显提升。
4. 参数调参与避坑指南:让诗不重样、不跑题、不翻车
4.1 三个必调参数:temperature、top-k/top-p、韵律过滤
不管你在“自动写诗.rar”里找到的是训练代码还是推理脚本,最终生成环节一定绕不开temperature。它的作用是把模型输出logits除以一个温度值,再做softmax把分数转成概率分布。温度越低,分布越尖锐,采样结果越接近概率最高的字;温度越高,分布越平坦,越容易选出平时很少出现的字。写诗这个场景,我用0.8作为起点,偏于稳妥又留一点意外感。低于0.5生成结果会变成复读机,高于1.2就容易出现“火山飘雪花”这种意象混乱的句子。
在深度学习生成脚本里,top-k和top-p是配合temperature使用的两个裁剪参数。top-k会先从所有候选字里挑出概率最高的k个,再在这个子集里重归一化采样;top-p则是按累计概率从高到低往下截断,直到覆盖概率超过p值为止。我的习惯组合是top_k=30、top_p=0.9:先用top-k把生僻字过滤掉,再用top-p把概率长尾裁掉,二者同时作用能有效避免句子中出现“啊”“兮”这类永远不该在五言绝句里出现的语气词。
韵律过滤则是生成之后的规则约束。诗和普通文本不同,尾字押韵是最低要求。我一般会把韵脚按“平水韵”中的常见韵部整理成字典,生成时检查每个结束字的韵母是否在指定韵部内,如果不在就重新采样。这个过滤不是训练阶段做的,而是推理阶段的兜底。它的作用是保证你调参之后生成出来的结果,至少看起来是一首“合格”的诗,而不是一段自动续写散文。
4.2 常见问题排查:乱码、OOM、复读机、不像诗
现象一:解压后txt打开全是乱码。原因是rar包在Windows下打包时,文本默认用了GBK编码,而你在macOS或Linux下默认用UTF-8打开。解决方法是重新用7z解压后,对文本做一次转码,或者直接用带encoding='gb18030'的Python脚本读取。优先用gb18030,它比gbk多覆盖了许多生僻汉字字符,能避免转码时抛UnicodeDecodeError。
现象二:训练脚本跑到一半报CUDA out of memory。原因基本是序列长度和批量太大。很多开源写诗demo默认把max_seq_len设成512,但诗句本身只有20到28个字,模型根本不需要那么长的上下文。解决方法是把max_seq_len调到64或128,batch_size减半到16或8。如果还想继续瘦身,可以使用梯度累积,用两个小batch累加梯度模拟一个大batch效果,显存占用能降一半。
现象三:生成的诗反复出现同一个字,比如“山 山 山 水 水 水”。这个现象的根源是temperature太低,导致模型每次都挑概率最高那一个候选。解决方法是调高temperature到0.9以上,同时给采样逻辑加一个no_repeat_ngram_size=4限制,这个参数能禁止连续四个字符成片重复。注意它是个硬约束,加得太小会影响正常意象复用,4是比较折中的值。
现象四:生成语句像散文换行,完全不押韵。这多半是模型学到了文本的“自然语句”分布,但没有学到诗的韵脚结构。解决思路分两步:第一步在数据预处理时,把训练样本按句尾韵脚分组,保证同一batch里的样本尾字都落在同一韵部;第二步在推理时加上韵律过滤,用规则修正模型输出。数据端和推理端同时调整,比只调任何一个参数都有效。
4.3 rar压缩包密码忘了:授权范围内的恢复思路
和“自动写诗.rar”相关的另一个高频问题,是rar压缩包密码忘了强制解压。我见过不少人在论坛求“强制解压工具”,但在非授权环境里跑暴力破解既不安全也没有正当性。做这件事之前,你必须先确认自己拥有这个压缩包或者已获得对方授权。在满足这个前提之后,才有继续讨论的意义。
第一件事,检查它是不是“文件名加密”。在7-Zip里用7z l列目录,如果文件名还能正常显示,说明只是内容加密,可以通过尝试密码恢复;如果文件名本身就是一串乱码,则rar包头和文件名都做了加密,恢复难度会高一个量级。大多数分享场景只对内容加密,这已经算好消息。
在授权前提下,不要一上来就挂百万字典暴力跑。更实用的是先列一个不超过20个候选密码的清单,比如项目名的缩写、作者ID、日期组合、常用弱密码。然后用7z t测试密码是否正确,这个命令只测试不解压,效率远高于完整解压。
7z t auto_poem.rar -p'Project2024'参数说明:t代表test mode,只校验压缩包完整性和密码正确性;-p'Project2024'指定候选密码。如果返回“Everything is Ok”,说明密码正确;如果出现CRC Error或Wrong password,就换下一个候选。把候选密码逐行写入passwords.txt后,可以用一个循环批量尝试:
while read pass; do 7z t auto_poem.rar -p"$pass"; done < passwords.txt这段命令会逐行读取密码,对同一个rar包反复做测试。需要注意的是它只适合小规模候选,一旦候选超过几百条就说明定位方向错了。密码恢复不是无底洞,你越了解这个包的来源,候选密码就越精准。我处理过的最快一次,密码就是作者自己在论坛ID后面加了一个年份,三行循环就出来了。
5. 让写诗结果“可宣称”:质量验证与一个进阶技巧
调参到最后,你面对的问题不是“代码能不能跑”,而是“生成结果到底算不算好诗”。这种时候我建议先做一个可量化的合规性验证。我自用的方法是把生成结果按五言或七言切分,逐句统计三个指标:句长是否达标、尾字是否在目标韵部、全篇重复字率是否低于10%。这三个数字能让你每次调参的产出变成可以对比的记录,而不是“感觉比上次更顺”。
合规率验证通过后,可以做主题词注入。这个进阶技巧特别适合写情感诗或咏物诗。做法是在采样前,给主题相关字在logits上加上一个偏置值,让它们从候选池里更容易被选中。
# 在softmax之前的logits上做主题加权 theme_words = {'月', '风', '花', '水'} for idx, token in enumerate(vocab): if token in theme_words: logits[idx] += 1.5这段代码的解释:遍历词表,如果当前字属于主题词集合,就把它对应的logits数值上调1.5。这个偏置越大,生成内容越偏向主题相关意象,但太大也会导致句子之间缺乏逻辑衔接。我从0.5开始往上试,一般不超过2.0,超过2.0以后诗句就会变成意象堆砌,比如“花月风月月”这类完全不成句的结果。
验证指标加上主题偏置之后,我还会做一个最简单的“图灵测试”:把模型生成的3首和从诗集里挑出的3首混在一起,让同事挑哪几首不是人写的。这个方法不严谨,但能一次性暴露两个问题——风格模仿能力和平仄错误。如果同事一眼挑出机器作品,问题通常不在参数,而在训练语料风格太单一,这时候要去扩充语料而不是继续调temperature。
我自己的习惯是,每次跑完一组生成,都把当时的随机种子、temperature、top_p这组参数和输出一起存成文件。自动写诗这类任务的随机性很强,不同时记录种子,哪怕参数一模一样,第二天复现出来也会是另一首完全不同的诗。这个习惯救过我很多次,因为“上次调出那句惊艳的句子”之后,最怕的就是找不到当时的状态配置。希望这些经验对你有所帮助。
本文还有配套的精品资源,点击获取