Dash错过了那个瞬间。Pip的围巾落在池塘边,他手里只剩下一则日志记录。能不能让一个本地图像模型,把这个画面画进村庄的故事书里?

这是llamadart系列实验的第四部分。Llama Village本身已经能用日志和截图复述一次运行过程,而这次是独立的尝试:用llamadart的ImageGenerationEngine,把一段样本事件想象成一个场景。两个本地模型,三组提示词,只盯一件事——你能找到那条围巾吗?

打开网易新闻 查看精彩图片

样本事件:一条卡在芦苇里的红围巾

样本事件很小:一条红围巾卡在村庄池塘边的芦苇丛里。提示词直接用Dart拼出来,不需要语言模型来改写它。

代码里定义了两个字段,一个是主体,一个是地点:主体是“卡在绿色芦苇中的红色羊毛围巾”,地点是“在一个小村庄的池塘边”。拼出来的提示词还加上了“雨夜”“温和的故事书插画风格”“不要文字”。

这些只是示例性的日志字段,并不是Llama Village已有的API。把事实和美术方向分开,是为了让游戏自己决定这张图到底在讲什么。

整个链路是这样的:Dart负责拼提示词,ImageGenerationEngine负责出图,并单独上报进度。

第一次尝试:SDXS,一个模型文件,一步生成

引擎在本地跑stable-diffusion.cpp。第一次尝试选了SDXS:只有一个模型文件,大约683 MB,配方只用一步生成。

实际输出是SDXS Q8_0,512 × 512,一步,guidance为1,seed为42。

图里有芦苇、有水、有房子、有雨。氛围是喜欢的。但认不出那条围巾——而围巾恰恰是这个场景被写进书里的理由。

那换个更亮的场景,会不会更容易看清?只把“雨夜”改成“晴朗的早晨”,模型、seed、尺寸和其他设置全部不动。

天亮了,雨没了。围巾还是没出现。

固定seed能帮我们在这套设置下比较不同提示词,但它并不锁定构图,也不保证在不同运行时版本和设备上得到完全相同的像素。

天气变了,缺失的物体没有回来。于是第三张图,直接让模型把围巾放到镜头正前方:一条红色针织羊毛围巾缠在绿色芦苇里,围巾占满前景,背后是池塘的水,雨夜,温和的故事书插画风格,不要文字。

这次有了能认出来的红色针织织物。同时也多出了额外的绿色布料,雨也不明显了。提示词起了作用,但没有让这张图变成一份精确的记录。

这就是故事书的边界:日志说的是发生了什么,插画想象的是它当时看起来什么样。如果游戏需要精确的角色面孔、位置,或者某个事件的证据,那就保留截下来的截图。

换更大的模型,结果会更好吗

也许更大的模型会更贴近场景。于是用同样的三组提示词试了SD-Turbo Q8_0加TAESD:512 × 512,一步,guidance为1,seed为42。TAESD是文档配方里的小型解码器,所以这次比较的是完整配方。

SD-Turbo,雨夜。前景芦苇更分明,但依然没有清晰可辨的围巾。雨比SDXS那张更不明显。

SD-Turbo,晴朗的早晨。芦苇之间出现了红色形状,但读不出是一条羊毛围巾。天气的变化也很微弱。

SD-Turbo,特写。两边边缘出现了能认出来的红色针织碎片,但没有满足“一条围巾占满前景”的要求。

就这个故事书场景而言,更偏好SDXS那种更柔和的风格。两个模型都不能可靠地遵循每一个细节。这是针对一个seed下三组提示词的视觉判断,不是一次通用的质量排名。

接近两倍的进程内存、三倍的模型存储,依然没能给出一张清晰呈现该事件的图。这个原型里会保留SDXS。这个选择只针对这些场景和设置;给SD-Turbo更多步数,或者换上它的完整解码器,结果都可能改变。

速度与内存:数字摆在这里

测试环境是M4 Max、64 GB内存、Metal、Dart 3.13.5、llamadart 0.11.1。每个配方都在全新进程里单独运行,文件已缓存。先对三组提示词做一轮预热,之后又测了三轮:每个配方九次生成。

生成耗时:SDXS为0.383–0.387秒;SD-Turbo为0.545–0.622秒。计时在task.result处结束,不含PNG编码和写盘。下载和模型加载不计入。

内存方面,进程RSS每20毫秒采样一次,覆盖初始化、加载、生成和保存全过程。这测的不是设备或GPU的总内存。

条件说明:渲染器关闭,跑在开发机上,而不是隔离的基准测试环境。

这次对比用的是TAESD,不是SD-Turbo的完整VAE。四步生成和完整解码器都没有测。两个模型版本和解码器版本都在可运行程序里固定住了。

想自己试这条围巾场景,四步调用

程序大致是四次调用:先检查当前构建和设备,再加载一个固定版本的模型源,下载管理器会做缓存;然后启动任务,在运行期间监听进度;最后等待完成,把得到的像素保存成PNG。

这是API的骨架。完整程序里会内联定义模型和请求,处理不支持的运行时,并释放引擎。

task.events会上报提示词编码、采样、解码等阶段,它不会流式输出成图。要拿图或者拿到失败信息,都得等task.result。程序会在finally里取消事件订阅,并在三张图全部完成后释放引擎。

用SDXS时,要显式设置steps为1、guidanceScale为1。这些设置属于这个蒸馏模型;把它们照搬到任意图像模型上,并不是一个有意义的比较。