首页 / 万利虚拟人

万利虚拟人:AI Avatar与实时角色交互

万利虚拟人聚焦AI Avatar的外貌、声音、口型、表情、动作与实时交互能力,是万利平台在角色呈现层的具体落地。相比皮肤和光影这些容易被看到的细节,万利虚拟人团队在实践中发现,眼神、口型之外的协同表演、以及长期互动中的角色一致性,往往才是决定虚拟人是否自然可信的关键。以下三篇文章分别讨论这三个方向。

AI Avatar眼神与存在感Lip Sync表情与动作Persona Consistency
万利虚拟人口型同步生成流程图
语音先被拆解为音素,再映射为对应视位,驱动嘴部形状——但准确的口型只是自然表演的起点

万利虚拟人技术专栏

万利虚拟人已经可以做到非常逼真的皮肤和面部以后,为什么眼神仍然可能比皮肤细节更容易让用户察觉它不是真人?

在做万利虚拟人的每一轮版本迭代评审时,我们习惯把用户反馈按感官维度拆开看。一个稳定出现的结果是:皮肤毛孔、法令纹、颧骨高光这些做到位之后,用户很少主动提起皮肤问题;但只要眼神对不上,几乎所有测试者都能在几秒之内说出"感觉它没在看我"。这不是主观偏好,而是感知优先级的问题——用户往往不是先注意到皮肤问题,而是先觉得对方好像没在看自己,这句话在用户访谈记录里出现的频率,比任何一句关于皮肤的评价都高。

这背后其实关联着一个更根本的概念——存在感。用户判断"对方是否真的在和我互动",很大程度上依赖眼神这一个信号,而不是整体的视觉精度。哪怕皮肤、光影已经做到很细腻的程度,只要视线方向、聚焦深度和交流场景对不上,用户的第一反应仍然是"这更像一段预先渲染好的动画,而不是正在回应我的角色"。皮肤瑕疵之所以更容易被原谅,是因为人们在照片、视频、直播里本就见惯了各种光线和画质造成的皮肤失真,大脑对这类偏差有一定容忍区间;但眼神对视是人类在社交互动中高度敏感的信号,哪怕只是很短暂的方向偏差,也会被单独识别出来,不会因为"整体画面看起来不错"而被忽略。

皮肤和眼神在技术上根本不是同一类问题。皮肤的逼真程度主要取决于素材精度——高分辨率贴图、次表面散射、法线贴图这些都可以在离线阶段反复打磨,一旦做好,渲染引擎每一帧都能稳定复现,几乎不受运行时状态影响。眼神完全不同,它是一套需要在每一帧实时决策的行为系统:视线要落在什么位置、什么时候眨眼、瞳孔要不要随光线和情绪变化、眼球在两次注视之间要不要有细微的扫视。这些参数不是渲染出来的,而是每一次交互里现算出来的,稍微出一点偏差,观众就能察觉——人类视觉系统对"是否被注视"有专门的神经机制,这套机制的分辨率,远高于我们对皮肤纹理的分辨能力。

这也是很多团队在早期投入上容易犯的一个误判:把预算大量堆在建模和材质上,觉得"脸做真了,眼神自然也就真了"。实际情况是,眼神的问题不会随着面部精度提升而自动解决,它需要单独的注视目标计算、单独的眨眼节奏模型,甚至需要单独的美术和动画规则去约束。我们在万利虚拟人的产品打磨过程中吃过这个亏——早期版本把资源集中在提升面部材质分辨率上,上线后收到的第一批用户反馈里,"眼神呆滞""好像在看我身后"这类描述占了相当大比例,而当时的皮肤评分其实已经不低。

后来的做法是把注视当成一条独立的产品线来做。以万利虚拟人内部一个原创虚拟主持人角色"念雪"为例——这是一个完全虚构的形象,仅用于产品测试——她的注视系统会持续跟踪对话者面部或摄像头位置作为默认目标,交流中出现停顿或需要"回忆"某个内容时,会有意让视线短暂移开再收回,模拟人类思考时自然的目光游移;眨眼频率不是固定间隔触发,而是带随机扰动的区间分布,避免出现机械的等时距眨眼,那种规律性反而比不眨眼更容易让人起疑。瞳孔大小也会随场景亮度和对话情绪做轻微联动,幅度很小,但足以让人感觉"眼睛是活的"。这套系统追求的不是眼睛本身好不好看,而是能不能撑起"对方在场、在关注我"这种存在感,这恰恰是皮肤材质无法提供的东西。

当然这套机制也有明确边界。如果输入端只是一个普通前置摄像头,系统很难精确得到用户瞳孔的实际落点,只能用面部关键点位置去近似估算注视目标,遇到多人同框、用户频繁移动镜头,或者直播场景里主持人要在观众弹幕和摄像头之间来回切换注意力时,这个近似就会打折扣,注视目标切换的时机也会出现轻微延迟。另外,眨眼和微扫视这些参数目前更多依赖规则和统计分布调出来的效果,而不是从大规模真实人类数据里学出来的行为模型,遇到强情绪场景比如惊讶或悲伤时的眼部反应,还是不如面部表情迁移做得细。这些边界短期内不会完全消失,但至少说明了一个方向:眼神这件事,从来不是靠堆更高精度的材质就能解决的问题。

万利虚拟人说话时嘴型已经可以跟随声音以后,为什么正确Lip Sync仍然不等于自然表演?

很多人第一次看万利虚拟人的演示视频时,会先去确认一件事:嘴型对不对得上声音。这几乎是行业里最容易被量化、也最容易被误当成终点的指标——播放一段语音,看嘴巴张合的时机和音节是否同步,只要不出现"对不上嘴"的违和感,很多人就会觉得这个虚拟人已经"做成了"。但如果把同一段素材放给稍微挑剔一点的用户看几十秒,反馈往往会变成"嘴型是对的,但感觉像是在念稿子"。这句话背后其实指向了一个更深的问题:嘴型正确只是及格线,不是自然表演的终点。

从技术链路上看,语音驱动嘴型这件事分成几步:先把音频切成音素,也就是语言学意义上的最小发音单位,比如"b""a""sh"这些;再把音素映射到对应的口型分类,也就是视位——因为不同音素在视觉上可能长得很像,比如"b""p""m"发音时嘴唇动作几乎一样,所以音素数量远多于视位数量,这是一个多对一的映射关系。系统实时解析音频得到音素序列后,按映射表切换到对应视位,再用插值让嘴型过渡平滑,这就是目前大多数实时嘴型同步的核心逻辑。

还有一个经常被低估的细节是协同发音——真人说话时,一个音素的口型会被前后相邻音素影响,比如某个元音单独发音时嘴唇是圆的,但如果紧跟在一个牵动嘴角的辅音后面,实际口型会被提前带动,出现过渡形态,而不是干净利落地切换。如果嘴型系统只是逐帧查表,把每个音素对应的视位机械地拼接起来,即使时间点分毫不差,看起来仍然会有一种"一格一格切换"的僵硬感,跟人类说话时口型连贯滑动的方式不一样。解决这个问题依赖插值算法在音素边界处提前预判下一个目标口型,让过渡曲线更贴近真实发音时的肌肉运动轨迹,这也是为什么同样标榜"音素驱动"的系统,做出来的自然度可以有明显差距。这套流程解决的问题很明确:让嘴巴动的时机和形状跟声音对得上。但它完全不涉及嘴巴之外的一切——脸颊怎么联动、下巴张合的力度、说话前后的表情铺垫,这些都不在音素到视位这条链路的管辖范围内。

这也是为什么"Lip Sync做对了"很容易被当成整个表演问题已经解决的信号。音素到视位的映射可以用一套明确的规则或模型去验证对错,做出一个客观能打分的指标;但"表演自不自然"是一种综合的主观判断,牵涉到几十块面部肌肉的协同、情绪一致性、甚至说话节奏跟停顿。很多团队包括我们早期,会把嘴型准确率当成项目验收的主要标准,因为它好量化、好演示,容易在评审会上直接播片对比。但真正决定用户会不会觉得"这是个在表演的角色"而不是"这是个在念台词的模型"的,恰恰是嘴型之外的那部分。

万利虚拟人在嘴型之外单独维护了一套面部协同规则:说话时下颌、脸颊、鼻翼会跟着嘴型幅度做轻微联动,音量大或强调某个词时,眉毛和上眼睑会有对应的抬升,这些不是从音频直接算出来的,而是叠加在视位结果之上的一层表情修饰;情绪层面,会先从文本或语气识别出大致的情绪倾向,比如陈述、疑问、强调、轻松,再让嘴角弧度、眼神张合幅度跟着这个倾向做整体调性上的匹配,而不是每一帧都各自为政;手势和身体姿态也会按语句的重音位置做粗粒度对齐,比如强调词出现时手部或肩部会有一个很轻的动作提示,让声音、表情、动作三者在时间轴上互相呼应,而不是各走各的节奏。这套组合做出来的效果,才是用户口中"感觉像在演"而不是"感觉在读"的来源。

这套系统目前也有明显没解决完的地方。情绪判断如果只靠文本或语气的粗粒度分类,遇到反讽、克制的情绪或者比较复杂的语义时容易判断错方向,导致表情修饰和实际内容对不上,比嘴型出错更容易穿帮;实时场景里,为了控制延迟,很多情绪相关的表情调整只能用短窗口的音频特征去近似预测,没办法像离线渲染那样看完整句再回头调整每一帧,这就注定了实时表演的自然度上限,短期内很难追上离线精修的效果。嘴型同步这件事,说到底只是给了表演一个骨架,真正的血肉还得靠嘴型之外的一整套协同规则去填补。

万利虚拟人从一个固定形象变成长期互动角色以后,为什么"角色设定不能乱变"开始和画质一样重要?

最初做万利虚拟人的时候,我们对"角色"的理解其实很单薄——一张脸、一套服装、一个声音,做完就算完成了一个角色。这个理解在只做单次渲染或者短视频输出时是够用的,因为角色只需要在这一次输出里保持一致。但一旦这个虚拟人开始承担长期互动的功能,比如某个虚拟主持人角色需要每天直播、每天跟观众聊天,或者某个AI陪伴角色需要跟同一个用户连续对话几十天,问题就变了:用户记得住这个角色上周说过的话、上周表现出来的性格,如果这周画面依然精致,但角色说话的口吻、态度、甚至对同一件事的立场变了,用户感知到的违和感,不比模型崩坏轻。

这背后的技术原因其实不难理解。虚拟人的对话内容大多由语言模型实时生成,每一轮对话严格来说都是模型根据当前上下文重新"想"出来的回应,而不是从一个固定剧本里取出来的台词。如果没有额外的约束层,模型完全可能在今天的对话里表现得热情外向,明天遇到类似问题却给出偏冷静克制的回答——这两种回应单独看都合理,甚至都很自然,但放在同一个角色身上连续对比,就会暴露出人格不连续的问题。画质是渲染引擎决定的,只要资产和渲染管线不变,画面质量天然具有稳定性;但性格、语气、立场这些属于生成内容的范畴,天然不具备这种稳定性,除非专门用规则、约束文档或者记忆机制把它钉住。

很多团队包括我们自己早期,会把角色设定当成项目启动阶段的一次性工作——写一份人物小传,定好年龄、性格关键词、说话习惯,评审通过就归档,后续开发精力全部转向画面和动作。这个假设隐含了一个错误:以为设定是静态资产,跟建模文件一样,做完就不会自己变化。但设定文档只是给模型的参考材料,真正每一轮对话里角色"活"成什么样子,取决于模型当时怎么解读这份参考材料、上下文里带了多少干扰信息、甚至用户当轮提问的方式有没有把角色引导偏。设定文档不会主动维持一致性,维持一致性是需要持续工程投入的事情,这一点常常被低估。

后面我们把角色一致性当成一个需要持续维护的系统去做,而不是一份写完就归档的文档。具体做法包括:给每个长期角色维护一份结构化的人设约束,把性格关键词拆成可判断的具体规则,比如"面对负面评价时语气克制、不反讽",而不是笼统写"性格温和";每一轮生成的回复会跟这份约束做一次轻量校验,语气或立场明显偏离时触发重新生成或调整;对于跨会话的长期角色,还会保留一份精简的角色记忆摘要,记录之前互动里体现过的关键立场和习惯用语,作为后续对话的上下文锚点,避免角色因为记不住自己说过什么而前后矛盾。以万利虚拟人内部一个原创的虚拟陪伴角色为例——这同样是一个完全虚构的产品测试形象——它对某些敏感话题的边界回应几乎是固定措辞,不会因为对话上下文不同而随意松动,这类"不能变"的部分会被单独标记出来,优先级高于让回答显得更灵活自然。

这套系统还需要应对一个容易被忽略的场景:同一个角色往往要同时出现在不同渠道,白天在直播间面对公开弹幕,晚上又要在私聊场景里做一对一陪伴对话。如果两边各自维护一套逻辑,很容易出现"直播间人设"和"私聊人设"悄悄分裂成两个角色的情况,即便观众和用户都以为自己面对的是同一个角色。我们的做法是让核心人设约束和边界规则在所有渠道复用同一份配置,只在语气的正式程度和话题范围上按场景做参数化调整,而不是分别写两套设定文档,避免维护成本和一致性风险同时上升。

这套机制目前也没办法做到万无一失。长对话里上下文越拉越长,早期设定的权重会被后面的内容稀释,一致性校验能拦住比较明显的偏离,但很难察觉那些语气上细微、逐步累积的漂移;遇到用户刻意用连续追问或者反复措辞去试探边界的情况,模型也有一定概率被绕开约束,说出跟角色设定不符的内容,这类情况目前主要靠事后复盘和规则补丁去收窄,没有一次性根治的办法。角色设定这件事本质上是个需要持续投入的工程问题,跟画质维护一样没有终点,只是行业过去更习惯把资源和关注度放在看得见的画面上,容易低估这部分投入的必要性。