简介:AI画汉字常“轮廓近似、细节尽毁”,症结不仅在生成端,更在评估端:整字识别式的裁判把汉字当成黑箱,奖励非黑即白、无法定位错误。本文解析三类裁判的失效机制,介绍基于部件与构型分解的结构感知评估思路,并给出示意性打分流程与落地建议,帮助开发者构建可定位错误、可指导优化的奖励信号。
让AI生成一张带中文的海报,最常见的翻车场景是:远看版式漂亮、氛围到位,凑近一看才发现某个字多了一撇、某个偏旁被挤成了四不像、部件之间比例失衡。整体轮廓接近,细节一塌糊涂。这不是某一家模型的偶发缺陷,而是当前文生图模型在汉字渲染上的通病,笔画越复杂,翻车越频繁。
从技术上看,汉字的生成难度天然高于英文:
但生成端难,并不是故事的全部。真正让“画对汉字”长期止步不前的,是评估端的系统性漏洞。
要持续提升生成质量,业界的通行做法是对预训练好的文生图模型做强化学习后期训练:模型针对同一提示词生成一批候选图,由“裁判”逐张打分,再用分数构造损失去更新模型。这条链路里,裁判打分细不细、准不准,直接决定模型能学到什么。
在中文文字生成任务里,这个裁判通常是OCR。OCR即光学字符识别,是让机器“认字”的通用技术:把图片中的文字区域识别出来,转成机器可读的文本。用它当裁判的逻辑很直接,把生成图里的文字截出来识别一遍,与目标文字一致给高分,不一致给低分。
逻辑看似闭环,实则埋着一个致命假设:把汉字当成一个不可拆分的整体来判定对错。
当OCR面对一个结构写坏的复杂汉字时,常见表现有三种:把整个字判成不认识的东西、硬猜一个形近字、或者干脆放弃输出。无论生成结果是错了一笔还是错了半边,只要OCR认不出来,裁判给出的都是同样的零分。
这相当于批改一份100道选择题的卷子,学生错一道和错九十道,得分完全一样。分数里没有梯度,模型自然学不到该往哪个方向改。
换成更聪明的多模态大模型来打分,会出现另一种失效:它会把海报上下文、提示词语境一起纳入判断,凭借语言能力“猜”出这个字应该是什么,然后给出满分,可图上的字形明明是错的。这种“蒙对”的假阳性比给零分危害更大,错误行为反而被当成了奖励。
还有一类专门检测错字的字形检测工具,能判断出某个字结构有问题,但输出方式是把整个字标记成一个异常符号,最终同样落到零分。这类方法不会被语义脑补欺骗,却仍然是非黑即白的判断:对,或者错,中间没有灰色地带,也给不出“错在哪、差多少”。
三种裁判形态各异,失效根源却是同一个:都把汉字视为不可拆分的最小单元,丢掉了“结构”这一层信息。而汉字的错误,恰恰就发生在结构这一层。
汉字系统有一个重要特性,可分解性:
这意味着一个关键事实:任何一个汉字写错,错误必然可以定位到某个部件、某组空间关系或某几笔上。“错”天然有位置、有程度。把这个先验用起来,评估就能从“对或错”变成“哪里对、哪里错、错多少”。
国内有研究团队正是沿着这条思路提出了改进方案:与其问“这个字认不认得出来”,不如先拆解、再比对、后聚合。完整流程可以拆成四步:
一个示意性的打分逻辑如下(仅用于说明评估思路,不代表任何具体系统的接口):
def structural_reward(img, target_char):# 1) 结构分解:整字 -> 部件树 + 空间关系tree = decompose(target_char) # 例:{"parts": ["尢", "介"], "layout": "左右"}# 2) 部件定位与切分regions = locate_parts(img, tree)# 3) 分层比对s_part = mean([part_sim(r, p) for r, p in regions]) # 部件形态相似度s_layout = layout_score(regions, tree) # 空间构型是否正确s_stroke = stroke_penalty(img) # 笔画增删、粘连程度# 4) 连续化聚合,而非二值判分return 0.5 * s_part + 0.3 * s_layout + 0.2 * (1 - s_stroke)
与整字判分相比,这套范式的关键差异在于:分数是连续的、有归因的。左边部件写对了、右边写错了,得分会明确反映“错在右侧”;部件全对但结构摆歪,结构层分数就会拖低总分。错误的程度与位置都被编码进了奖励信号。
如果要为中文文字生成搭建一套结构感知的评估管线,以下几点值得注意:
从“整字对不对”到“结构哪里错”,看似只是评估粒度的变化,实质是把汉字数千年沉淀下来的构型先验,正式注入了机器学习的奖励回路。裁判不再只宣布生死,而是像一位语文老师那样批改每个部件、每一处布局。当奖励信号足够细,“画对中文字”才有可能从偶然事件变成可训练、可复现的必然结果。这套思路也不难延伸:日文汉字等更广泛的CJK场景、可控生成与版式理解的结合,都是顺理成章的下一步。