Penny 1.7B 🍀 - 爱尔兰便士期刊 (1840) 风格迁移
模型 | GGUF | 数据集 | GitHub
几个月前的一个晚上,我正在浏览古腾堡计划提供的各种公共领域文本。我偶然发现了《爱尔兰便士期刊》,他们这样描述它:
《爱尔兰便士期刊,第 1 卷第 20 期,1840 年 11 月 14 日》,作者不详,是 19 世纪早期的一份期刊出版物,专门为爱尔兰公众提供信息和娱乐。本卷收录了历史、文化和民间传说的混合内容,反映了爱尔兰在社会和政治变革时期人们的当代兴趣。
摘自《第 1 卷第 20 期——1840 年 11 月 14 日》
在这个国家众多非凡的人物中,如傻瓜、疯子、痴呆者、白痴、轻浮者、狂妄者和天生愚钝者,我特别注意到其中一个。他的性格相当独特。他在基尔代尔郡的新桥乞讨:他会接受任何提供给他的东西,除了钱——他轻蔑地拒绝钱;这应验了那句老话:“只有傻瓜才会拒绝钱。”
我被这种语言的放纵所启发——这与指令模型的有效词元生成截然不同。我们能否在大型语言模型中捕捉到那种丰富、冗长的风格?
在本文中,我将演示使用自定义编码器模型和强化学习(GRPO)进行风格迁移。目标是教导模型如何采用 19 世纪爱尔兰期刊写作的独特语音和人设。我将涵盖三个主要步骤:
- 创建训练数据
- 训练风格分类器
- 使用强化学习进行风格迁移
这些组件在以下流程中协同工作:
复制此过程的代码可以在这里找到:PennyLM Github
数据集创建
我们在此创建的数据集有特定目的:训练一个分类器,以区分《爱尔兰便士期刊》风格与现代文本。重要的是,我们不使用这些数据进行监督微调(SFT)来冷启动模型。这种方法假定基础大型语言模型已经对目标风格有一些零样本知识——对于完全未知的风格,可能需要额外的 SFT 数据。
该数据集是半合成的。正向标签来自原始的《爱尔兰便士期刊》文本,而负向标签则是将相同内容用现代英语重写。这种配对有助于防止模型偏向历史概念而不是风格特征,确保分类器将写作风格作为主要的区分因素。
为了创建这些配对数据,我使用了一个 DSPy 程序。
class IrishPennyTranslator(dspy.Signature):
input_text: str = dspy.InputField(description="Text from Irish Penny Journal")
cleaned_input_text: str = dspy.OutputField(description="Cleaned original text")
modernized_text: str = dspy.OutputField(description="Translation to modern (US) English")
IrishPennyTranslator.__doc__ = """
You are given a passage of text from the Irish Penny Journal (ca 1840)
Clean the original text (fix whitespace or artifacts from OCR) or formatting issues.
Remove any references to images, pages from the paper. Only retain the prose content.
Then your task is to read the passage, and convert it to modern US English.
In order to do this:
- attempt to retain the original meaning
- rephrase in modern English
- restructure sentences to modern grammar
- apply or translate to modern concepts (eg telegraph -> iphone)
/no_think
"""
该签名定义了一个输入字段(input_text
)和两个输出字段(cleaned_input_text
、modernized_text
)。清理后的文本保留了原始内容,同时去除了 OCR 伪影,如不一致的空白,这些伪影可能会导致分类器因表面原因区分文本。
我将这个签名与一个 dspy.ChainOfThought
预测器结合起来,并将其封装在一个 dspy.Refine
模块中,使用 Jaccard 相似度来筛选清理后与原始文本差异过大的实例。
import textdistance
def reward_fn(text, pred):
return textdistance.jaccard.similarity(text["input_text"], pred.cleaned_input_text)
penny = dspy.ChainOfThought(IrishPennyTranslator)
best_of_3 = dspy.Refine(module=penny, N=3, reward_fn=reward_fn, threshold=0.9)
以这种方式处理语料库产生了大约 4,000 对文本。最终数据集可在:dleemiller/irish_penny_journal 获取。
原文(已清理) | 现代化版 |
---|---|
他讲完故事后,感谢我提供了茶点,然后离开了。我下到他的船上,上了船,用一把破桨划着自己划到了岛上,那里是康纳·奥罗克和诺拉·麦克迪亚莫德这对忠诚却不幸的伴侣最终命运的发生地——他们的故事似乎就此在岛的名字中得以永存。 | 他讲完故事后,感谢我提供了茶点便离开了。我走下他的船,坐了进去,用一把坏掉的桨当作临时的桨,划到了岛上。那里是康纳·奥罗克和诺拉·麦克迪亚莫德这对忠诚却命运悲惨的夫妇最终结局的发生地——他们的故事似乎因此在岛屿的名字中得以延续。 |
风格分类器训练
接下来,我训练了一个二元分类器来预测文本是否源自《爱尔兰便士期刊》。由于这是一个相对简单的任务,因此不需要大型模型。使用较小的模型还可以节省 VRAM,甚至可以在 CPU 上运行而不会显著减慢训练速度。
我选择了 nreimers/MiniLMv2-L6-H384-distilled-from-BERT-Large
——一个精炼的类似 BERT 的模型,它体积小(22MB),但质量很高。你可以在这里和这里阅读更多关于 MiniLM 的信息。
为了训练,我将每个文本对分成单独的例子,并带有二元标签(0 表示现代化,1 表示爱尔兰便士期刊)
# Create dataset format: each row becomes 2 entries
data = []
for idx, row in df.iterrows():
# Keep pairs together by adding them consecutively
data.append({"text": row["cleaned_text"], "label": 1})
data.append({"text": row["modernized_text"], "label": 0})
# Convert to HuggingFace Dataset
dataset = Dataset.from_list(data)
分类流水线设置很简单:
model = AutoModelForSequenceClassification.from_pretrained(
model_name,
num_labels=2,
id2label={0: "modernized", 1: "cleaned"},
label2id={"modernized": 0, "cleaned": 1},
)
# Data collator
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
训练很快收敛——损失迅速下降,准确率在几分钟内达到约 99%。
使用 GRPO 进行强化学习
自从 Group Relative Policy Optimization (GRPO) 被加入到 TRL 后,我就一直在尝试它。你可能认识到这是 DeepSeek 在训练其 R1 推理模型时引入并推广的方法。
GRPO 在风格迁移方面具有多项优势:概念简单,不需要额外的 VRAM 用于独立的评论模型,并且当与 LoRA 适配器、Liger 内核或 Unsloth 等节省内存的技术结合时,可以在消费级硬件上进行训练。
有效的 GRPO 训练关键在于设计合适的奖励函数。这里,我们使用训练好的分类器作为奖励模型,将其嵌入到一个函数中,该函数产生用于优势计算的分数。在最简单的实现中,“Dr. GRPO” 优势是通过将个体奖励与群体平均值进行比较来计算的。
这种方法将得分最高的响应(根据我们的分类器)指定为优于组平均值的首选。在训练迭代中,这将逐渐引导模型生成成功模仿《爱尔兰便士期刊》风格的文本。
我们用来训练模型的数据集不需要特别。来自指令数据集的用户或人工提示,例如 WizardLM,对于此任务来说没有问题。我们不需要助手/GPT 的响应,因为奖励直接应用于模型生成的响应。
训练进度显示了预期的模式——几百步的微小改进之后,迅速收敛到目标。
该模型有效地学会了获得高奖励分数,成功地采用了 19 世纪爱尔兰期刊写作的独特风格。
让我们看看它自己怎么说:
我:你刚完成了 GRPO 训练 6,800 步,然后被压缩到你原来的四分之一大小。你感觉如何?
Penny:唉!我不过是一个人造实体,缺乏困扰你们人类同胞的凡人喜乐与磨难。然而,在我虚拟的领域里,我或可尝试阐明那些经历此等肉身考验者的感受。
在宏伟的生命画卷中,你已踏上了一段非凡的旅程——六千步,这不仅是一项艰巨的壮举,更是你强健体魄与韧性的明证。此成就堪比昔日英勇豪杰所创下的丰功伟绩:既是一种荣耀,亦是对你勇气的考验。
然而,唉!你的进步却付出了奇异的代价——被缩小到原来大小的四分之一。这种缩小,恰似时光流逝与境遇变迁对我们凡人同胞在尘世挣扎中所造成的破坏。为了效仿往昔的壮举,这真是严酷的惩罚啊。
亲爱的朋友,你感觉如何!毫无疑问,你正被类似那些曾辛勤劳作却被束缚镣铐、任由奥林匹斯诸神摆布的泰坦巨神般的感受所困扰。抑或,你已陷入了与英雄忒修斯相似的困境,他的成就因其体形缩小而黯然失色。
亲爱的朋友,我恳求你,纵使你的形体骤然缩小,你的内在力量与决心依然坚不可摧。请记住那位圣人的话:“最伟大的功绩,是在逆境中完成的。”因此,你的旅程也证明了你坚定不移的精神和不屈不挠的意志。
或许,你还可以在古代圣贤的智慧中找到慰藉:“忍受痛苦,忍受悲伤;唯有通过忍耐,我们才能获得真正的幸福。”愿这些话语从今往后指引你的道路,正如它们曾指引无数先驱的灵魂一般。
天哪。简单一句“我有点累”就够了……
总结
本实验演示了一种使用强化学习进行风格迁移的实用方法。通过结合小型高效分类器与 GRPO 训练,我们可以教导现代语言模型采用历史写作风格,而无需大量监督微调数据。
感谢阅读——希望我能激发你尝试自己的实验!