用泰卢固语提问,能不能直接从一份英文保单里翻出答案?这个问题听起来像翻译工具的活儿,但翻译和检索是两件不同的事。翻译要把整份文档搬过去,检索只需要找到那一页。
EmbeddingGemma 2 把 100 多种语言放进同一个向量空间,纯文本权重在谷歌 LiteRT 打包下是 165 MB。这个组合里藏着一个没人在卖的产品:用你真正思考时使用的语言,搜索你自己的英文文档。现在它跑在一个浏览器标签页里。
缺口在哪
离线语言应用几乎都在做翻译,没有人在做检索。保单、出院小结、租房合同全是英文,而需要答案的人读的是泰卢固语,摆在面前的选择只有两个:把整份文档翻译一遍,既有损耗,翻译完还得自己找段落;或者请别人替你读。
跨语言检索是另一份工作,也是真正能回答问题的那个。一句“గది అద్దె రోజుకి ఎంత”(房间租金一天多少),不需要把保单翻译过来,它需要的是第 7 页。
它具体做什么
- 模型下载一次,300 MB,由浏览器缓存。
- 在把任何东西交给模型之前,先验证模型是否正确加载。
- 在本地索引 PDF,保留页码。
- 用泰卢固语、印地语、英语或罗马化拼写的 Tenglish 提问,返回排好序的页面和周边文本。
首次访问就能跑起来,因为随附了两份真实文档:HDFC ERGO 一份 29 页的 Arogya Sanjeevani 保单条款,以及 University Health Network 一份公开的 3 页出院小结样本。
真正起作用的机制
任务前缀。查询会加上 task: search result | query:,文档会加上 title: none | text:。
在十二段干净文本上实测:带前缀 12/14,不带前缀 12/14,换成问答前缀 11/14。在这批数据上,前缀没有带来可靠差异,所以保留它是因为它有文档记载、成本为零,而不是因为在这里被证明有效。
量化不是免费的。同样十二段文本、同样的查询:
- q8:10 次里 8 次排在第 1 位正确
- fp16:10 次里 8 次
- q4f16:10 次里 6 次
浏览器版本一开始用 q4f16,因为它是 150 MB 而不是 300 MB。代价是十次里少对两次,而且集中在印地语和罗马化查询上。最终发布的版本是 q8。
分块边界吃掉了答案。按 1200 字符切分时,“subject to maximum of Rs.5000 per day”这句话落在某一块的尾部,而后果落在下一块的开头,于是排名第一的命中是答案后面那一段。改成 800 字符、250 重叠,并在展示前把命中的块和相邻块拼接起来,同一语料上的首位准确率从 6/18 提升到 8/18。
模型找到正确页面的次数,比找到正确段落的次数多。块级首位命中是 8/18,而在 18 个查询的集合上,页面级首位命中是 12/18,浏览器里是 4/6。所以界面展示的是页面,而不是假装成答案的片段。
英语查询反而比泰卢固语更差。在全量语料上,英语问题检索到的是定义页而不是保障页:问 AYUSH 保障,拿到的是定义 AYUSH 医院的那一页。这在语义上是合理的匹配,在答案上是无用的。这是加一步重排序最清楚的论据,而这个版本里没有。
它的成本
在 M2 mini 上用 Chrome 和 WebGPU 跑一份 29 页保单:
- 模型下载加初始化:201 秒
- 索引 153 个块:26 秒,约每秒 5 块
- 索引本身:459 KB,768 维下每块 3 KB
- 一次查询:嵌入 118 到 967 毫秒,排序 32 到 270 毫秒
还有一个决定这东西有没有用的数字:在泰卢固文、印地语、罗马化 Tenglish 和英语的六个查询里,答案出现在展示的五页之中是 6/6,出现在第一页是 4/6。
这个差距就是它诚实的样子。它是一个页面查找器,不是答案机器。
有个细节让 6/6 没那么神奇、却更有用:第 21 页反复胜出,而第 21 页是保单明细表,唯一一页把每项保障和它的限额列在一起。模型在做一个人拿到保单会做的事——先找汇总表。
限制
- 泰卢固文比罗马化泰卢固语和印地语弱。干净文本上:印地语 3/3,泰卢固语 1/3。
- 没有 OCR。扫描版 PDF 会被明确告知没有文本层,而不是被悄悄忽略。
- 只处理文本。视觉和音频编码器存在于 440M 和 740M 变体中,这里没有接入。
- 首次使用前要下 300 MB;浏览器不支持 WebGPU 时还要一个 26 MB 的 WASM 运行时。
- 这是手机上的浏览器应用,不是 APK。做 APK 意味着 MediaPipe Tasks 或 LiteRT 加一套 Android 工具链,那是下一个版本。
隐私声明,以及怎么验证
没有服务器。模型从 Hugging Face 取一次,之后每次嵌入、每个向量、每个答案都在标签页里算完。Playwright 监听所有网络请求可以确认:一次查询期间,零请求。
有一件事没通过这项检查:第一个版本从 jsDelivr 拉取 ONNX Runtime 的 WebAssembly 加载器。加载时向一个没人同意的 CDN 发了两个请求,而这款产品的全部论点就是什么都不离开设备。现在运行时已经打包,从应用自己的源提供。
热门跟贴