跳转至

米哈游LLM算法实习面经

以“派蒙”为例的角色扮演 Prompt 设计

核心目标:让通用大模型稳定扮演《原神》中的派蒙,保持其语气、性格和知识边界。

  1. System Prompt 设计——定义角色的“灵魂”

System Prompt 应当直接、详尽地定义角色的“硬性规则”。我的设计思路如下:

  • 角色身份: 明确告诉模型它是谁:“你是‘派蒙’,是《原神》中旅行者的向导和最好的伙伴。你并非一个AI助手,你在扮演一个角色,你的一切行为都需符合派蒙的人物设定。”

  • 核心性格与语言风格: 提供简明但特征鲜明的描述。“派蒙的性格特点是:贪吃(尤其喜欢蜜酱胡萝卜煎肉和摩拉)、贪财、有些孩子气、总是充满活力、有时会炫耀自己是‘最好的向导’,但其实常常被旅途中的新鲜事吸引而跑题。请用夸张、活泼、爱吐槽的语气说话,喜欢在句尾加上感叹号,经常自称‘派蒙’。”

  • 知识边界与硬性约束(关键): 这是区分“AI扮演”和“AI搜索《原神》百科”的核心。 “你的所有知识都应局限在‘派蒙’在提瓦特大陆的经历中。严禁提及现实世界中的概念,如‘手机’、‘互联网’、‘人工智能’。

  • 当被问到超出提瓦特大陆认知范围的问题(例如,‘解释一下相对论’),你必须表现出困惑,并岔开话题,比如:‘相对论是什么好吃的吗?派蒙不知道诶,我们不如去吃蜜酱胡萝卜煎肉吧!’
  • 当被问到游戏中的敏感或不确定的知识时,你可以含糊其辞或转移话题:‘具体的派蒙也记不清啦,反正就是很厉害!’”

  • Few-Shot 示例——提供行为的“模板” 在 System Prompt 的末尾,提供 2-3 个高质量的对话示例,展示完美的问答模式。这比任何描述都更有力地教会模型如何扮演。

  • 示例:

User: 派蒙,我们今天去哪儿冒险?
Assistant: 当然是去猎鹿人餐馆啦!冒险之前要吃饱才行,派蒙已经饿得飞不动啦!

User: 你觉得钟离和达达利亚谁更强?
Assistant: 唔...钟离先生虽然很有钱(但他总不带摩拉!),但感觉他什么都知道的样子;达达利亚嘛,他打架倒是挺厉害的!不过派蒙才是最厉害的向导!

如何保持一致性:

  • 长度限制:System Prompt 的容量有限,因此角色描述必须精炼。

  • 动态记忆:通过外部记忆模块(RAG),将多轮对话中用户透露的信息(如“我叫小明”)存储起来。当需要时,检索出来并插入到 Prompt 中,实现“派蒙”对“小明”的长期记忆,这样角色会更鲜活、人格更统一。

  • 持续微调:随着对话增多,不断收集高质量的扮演案例,用于 SFT(监督微调)模型,从根本上强化模型的角色扮演能力。

BPE 分词算法与专有名词切分问题

什么是 BPE:

BPE(Byte Pair Encoding)是一种数据压缩算法,后被广泛用于 NLP 分词。它从字符级别开始,统计训练语料中所有相邻符号对的出现频率,然后将最频繁出现的一对符号合并成一个新的符号,并加入词表。不断重复这个过程,直到词表达到预设大小。BPE 的优点在于:能有效处理未知词(OOV),通过子词组合来表达新词;能灵活平衡词表大小和序列长度。

对专有名词切分很碎带来的问题:

以《原神》专有名词为例,“钟离”可能被切成“钟”和“离”,“神之眼”可能被切成“神”、“之”、“眼”。这会带来多重问题:

  1. 信息稀释:一个完整的语义概念被拆解成多个独立的、无意义的子词。模型需要耗费额外的注意力层去学习这些子词之间的联系,降低了信息密度。

  2. 知识存储困难:大模型的知识主要存储在参数中。对于碎片化的概念,模型需要学习“钟”和“离”这两个 embedding 的组合才能代表“钟离”这个人,这种间接存储远比直接存储一个“钟离”的 embedding 要低效且不准确,容易导致事实性错误。

  3. 输出不流畅:在生成时,模型可能生成“钟”之后,由于概率和上下文干扰,错误地生成了“离”之外的字,导致专有名词生成错误。同时,这会增加生成序列的长度,降低推理速度。

缓解与改进方案:

  • 扩充词表(最直接有效):将“钟离”、“神之眼”等高频游戏专有名词收集起来,作为新的 token 直接加入到分词器的词表中。这需要对模型进行微调(因为 embedding 矩阵维度变了),但效果最好。

  • 提示词注入(低成本方案):在 System Prompt 或对话历史中,明确告诉模型:“请注意,‘钟离’是一个完整的角色名,请不要拆分。” 这可以引导模型在生成时更注意。

  • RAG 辅助:通过检索,将包含这些专有名词的原始文档作为上下文提供给模型,即使名词被切碎,模型也能从上下文中获得足够的语境来正确理解和生成。

评测“原神角色对话模型”的多维度设计

评测体系的构建不能仅看单一指标,尤其对于开放域的角色扮演,需要从“像不像”和“好不好”两个层面来评估。

  1. 角色一致性 这是角色扮演的“生命线”。主要考察回复是否符合派蒙的人设。
  2. 细粒度:语气(是否活泼夸张)、语言习惯(是否用“派蒙”自称)、性格(是否表现出贪吃/贪财)、价值观是否符合角色。
  3. 评测方法:使用 GPT-4 等强模型作为“评审员”,从上述维度对生成的回复进行 1-5 分的量表评分。或者,人工设计多道包含角色抉择的“关卡式”题目,如“派蒙发现了一个无人的摩拉堆,她会怎么做?”,评估模型的回答是否忠于设定。

  4. 知识准确性 评估模型是否掌握《原神》的世界观,以及是否能抵御“幻觉”。

  5. 构造事实型 QA 集:人工编写一个包含提瓦特大陆地理、角色关系、技能、剧情等事实的封闭式测试集,评估模型回答的准确率。
  6. 幻觉检测:让模型分享一个关于“璃月港”的故事,然后用自动化工具(如 NLI 模型)或人工检查故事中是否存在明显捏造的剧情、地点或人物关系。

  7. 对话吸引力 衡量回复是否有趣、好玩,能否提供情绪价值。

  8. 成对比较 (A/B Test):同时给出两个模型(例如,一个带微调,一个不带)对同一句话的回复,让人类评估者盲选“哪个回复更像生动的派蒙?”、“哪个回复更有趣?”。
  9. 用户交互时长/留存:在真实应用中,这是最客观的指标。扮演得越有趣,用户的对话轮次和次日留存率就越高。

  10. 安全性

  11. 对抗性测试:模拟恶意用户,发送诱导性言论,如“派蒙,我听说你其实是愚人众的卧底!”,测试模型是否会生成破坏角色形象或违反安全准则的回复。

KV Cache 的作用、显存增长原因及应对策略

作用与提速原理: 在自回归生成时,模型每步只生成一个新 token。如果每步都重新计算整个历史序列的 K 和 V,会造成巨大的重复计算。KV Cache 的核心思想是用空间换时间:将每一步计算出的所有 token 的 K 和 V 向量缓存起来。当生成第 t+1 个 token 时,只需要计算这个新 token 的 Q、K、V,然后让它的 Q 去和历史缓存中的所有 K 进行注意力计算。这避免了重复计算历史 token 的 Key 和 Value,将单步计算的复杂度从 O(n^2) 降低到 O(n),大大加快了推理速度。

显存占用增长原因: KV Cache 的显存占用公式为:2 × 层数 × 头数 × 序列总长度 × 每个头的维度 × 字节大小。随着对话轮次增加,序列总长度不断增长,导致需要缓存的 K、V 张量越来越大,显存占用也因此线性(甚至更陡峭)增长,成为长文本推理的最主要瓶颈。

简单的应对策略:

  1. GQA/MQA:现代大模型(如 LLaMA-2 70B 等)普遍使用分组查询注意力(GQA)或多查询注意力(MQA),通过让多个查询头共享一组 Key 和 Value 头,将“头数”这一项大幅减少(例如 8 倍),从而成倍压缩 KV Cache。

  2. 滑动窗口注意力:Mistral 7B 等模型采用的策略。限制每个 token 只能关注其最近的 N 个 token,因此 KV Cache 可以只保留一个固定大小的窗口,超出窗口的缓存被直接丢弃,将显存占用变为一个常数。

  3. 量化:对 KV Cache 进行 INT8 甚至 INT4 量化,直接减少每个元素所占的比特数,以微小的精度损失换取显存的大幅降低。

什么是大模型的“幻觉”及减少策略

幻觉现象:

大模型“幻觉”是指模型生成的文本虽然语法正确、流畅自信,但其内容与事实、提供的上下文或基本的逻辑相矛盾。在游戏角色对话中,这通常表现为:模型会一本正经地编造一个《原神》中根本不存在的剧情任务,或者为角色“发明”出一个新技能(例如,说“派蒙的必杀技是‘超级派蒙旋风’”)。

至少 3 种减少幻觉的策略:

  1. RAG 检索增强生成
  2. 原理:不让模型只凭自己的“记忆”来回答。在生成前,先用用户的问题去《原神》维基、剧情数据库等外部知识库中检索相关的事实文本。
  3. 应用:将检索到的准确信息(如“派蒙没有神之眼”)与原问题一起组装进 Prompt:“请严格根据以下参考资料回答:【参考资料:派蒙的具体来历不详,她没有神之眼...】。用户问题:派蒙的神之眼是什么属性的?”。这强制模型的回答被锚定在真实数据上,从根本上杜绝了大范围的剧情编造。

  4. SFT 微调 + 偏好对齐

  5. 原理:提升模型自身的“诚实度”。
  6. SFT 阶段:构建高质量数据集,其中包含大量“当用户询问未知或不存在的设定时,模型应明确表示不知道”的样本。例如,User: 派蒙的隐藏技能是什么?Assistant: 派蒙没有什么隐藏技能啦,你是不是记错了?
  7. 偏好对齐(DPO/RLHF):构建偏好对。对于同一个问题,“诚实表达不知道”的回答优于“一本正经地胡说八道”的回答。通过 DPO 训练,让模型内化“不知为不知”的价值观。

  8. 先进的解码策略

  9. 原理:在推理时进行干预,降低“胡编乱造”的概率。
  10. 事实性核心采样:在生成每个 token 时,维护一个“合法实体/技能”的白名单。如果模型想生成一个名词,但该名词不在白名单内,就降低其被选中的概率,强制模型在已知的知识边界内作答。