kjarni-wasm

中文文档
0.4.3发布于 2026/11/04MIT OR Apache-2.0TypeScriptES Module零依赖

在你的网页中运行转换器模型:嵌入、分类、重新排序、语义搜索和web Worker中的聊天。与PyTorch相同的输出,没有服务器。

中文使用文档
文档目录12 节
  1. 复制这个,它就运行了
  2. 快速浏览
  3. 为什么是工人?
  4. 加载模型
  5. 分类
  6. Reranking
  7. 闲谈,聊天
  8. 清理
  9. 需求
  10. 模型
  11. 同样的引擎
  12. 制作自己的 .kjq

kjarni: local AI inference in a single native library

kjarni-wasm

在网页中运行变压器模型。与PyTorch相同的输出,没有服务器。

Kjarni是一个转换器推理库,这是它的WebAssembly版本: 嵌入、分类、重新排序、语义搜索和浏览器聊天, 在Web Worker中运行,所以页面永远不会冻结。同样的引擎为 Python, c#, Go, c++和Rust。

npm i kjarni-wasm

或者没有捆绑器,直接从CDN:

<script type="module">
  import { Kjarni } from "https://cdn.jsdelivr.net/npm/[email protected]/dist/index.js";
</script>

复制这个,它就运行了

一个文件,没有安装任何东西。另存为 quickstart.html,提供目录服务; 打开它:一个真正的模型下载并按意思排列三个句子。

curl -sO https://raw.githubusercontent.com/olafurjohannsson/kjarni/main/crates/kjarni-wasm/examples/quickstart.html
python3 -m http.server 8000
# then open http://localhost:8000/quickstart.html

需要服务器,因为ES模块无法加载 file://. 任何静态 服务器就行。

<pre id="out">starting…</pre>
<script type="module">
  import init, { WasmModel } from "https://cdn.jsdelivr.net/npm/[email protected]/pkg/kjarni_wasm.js";
  await init();

  const url = "https://huggingface.co/olafuraron/all-MiniLM-L6-v2-q8/resolve/main/all-MiniLM-L6-v2-q8.kjq";
  const model = WasmModel.from_quantized(new Uint8Array(await (await fetch(url)).arrayBuffer()));

  const texts = [
    "How do I get my money back?",
    "What is your refund policy?",
    "The weather in Reykjavik is unpredictable.",
  ];

  // Normalised, so a dot product is the cosine similarity.
  const flat = model.encode(texts, true);
  const dim = flat.length / texts.length;
  const vec = (i) => flat.subarray(i * dim, (i + 1) * dim);
  const cosine = (a, b) => a.reduce((sum, x, i) => sum + x * b[i], 0);

  out.textContent = `related:   ${cosine(vec(0), vec(1)).toFixed(4)}\n`
                  + `unrelated: ${cosine(vec(0), vec(2)).toFixed(4)}`;
</script>
related:   0.5268
unrelated: -0.0470

这将直接导入wasm模块,而不是导入 Kjarni 包装器,以便运行 在主线程上,没有Worker:对于一个只编码了几个句子的页面来说很好, 不是用来聊天的。使用 Kjarni 有关更大的内容,请参阅Chat部分。

分数与本地库略有不同(0.5510 / -0.0630),因为 浏览器模型是int8量化的。排名是一样的,这是什么搜索 用途。

快速浏览

import { Kjarni } from "kjarni-wasm";

const kjarni = await Kjarni.load({
  encoder: "https://huggingface.co/olafuraron/all-MiniLM-L6-v2-q8/resolve/main/all-MiniLM-L6-v2-q8.kjq",
});

const [doctor, physician] = await kjarni.encode(["doctor", "physician"]);
console.log(Kjarni.cosine(doctor, physician));   // 0.8598

// or in one call
console.log(await kjarni.similarity("doctor", "physician"));

该URL是一个真正的、公开的23 MB文件。它只下载一次,浏览器就会缓存,其他内容就不会离开电脑。看到 模型 对于其余部分,在生产中使用您自己的原产地而不是盗链。

每个方法都返回一个promise,工作发生在工作线程上。一个模型 在页面继续绘制时加载或生成回复。

为什么是工人?

推理是计算绑定的和同步的。在主线程上,对批处理进行编码 冻结标签,只要它需要,并生成一个聊天回复冻结它 秒。这是浏览器AI功能最常见的表现方式 坏了。

这个包把所有这些都放在一个工人身上,给你承诺,所以你从来没有 想想看。

加载模型

模型是 .kjq 文件:配置,tokenizer和int8权重在一个下载。

const kjarni = await Kjarni.load({
  encoder:    model("all-MiniLM-L6-v2-q8"),
  classifier: model("distilbert-sentiment-q8"),
  reranker:   model("ms-marco-MiniLM-L-6-v2-q8"),
  onProgress: (capability, loaded, total) => {
    console.log(`${capability}: ${Math.round((loaded / total) * 100)}%`);
  },
});

只加载您使用的内容。每个模型都是一个真正的下载,从23mb的MiniLM到 一个聊天模特几百块,所以 onProgress 值得连接到进度条。

字节被传输到工作线程而不是被复制,这很重要:复制一个 500mb模型是一个可见的暂停和双倍峰值内存。

分类

const [result] = await kjarni.classify("This is wonderful");
console.log(result.label, result.score);   // POSITIVE 0.9999

const batch = await kjarni.classify(["Great service", "Worst purchase ever"]);
console.log(await kjarni.labels());        // ["NEGATIVE", "POSITIVE"]

Reranking

将查询和文档一起评分,这明显比比较更准确 嵌入的。索引指向输入,因此您可以保留自己的id。

const ranked = await kjarni.rerank("how do I cancel?", documents, 5);
for (const { index, score } of ranked) console.log(score, documents[index]);

闲谈,聊天

一个0.5B语言模型在选项卡中运行,令牌在解码后到达。

const kjarni = await Kjarni.load({
  chat: model("qwen05b-q8"),
  chatModelId: "qwen2.5-0.5b-instruct",
});

let out = "";
for await (const piece of kjarni.chat("Explain RAG in one sentence.")) out += piece;

这是有效的,因为权重在内存中保持块量化。Wasm32代表a 单次分配 isize::MAX,原来是2gb, Qwen2.5 0.5B扩展到f32 需要1.98 GB,因此预先进行量化的加载程序会在加载时捕获。这个 .kjq 容器携带引擎就地读取的块量化权重,即 500mb而不是1.98 GB,解码速度比f32快而不是更慢。

在笔记本电脑CPU上,预计每秒会有几个令牌。在Web Worker: generation中运行它 占用线程直到它返回,因此在主线程上,TAB停止绘制 对于整个回复。

chat() 完成提示;它不转弯。多回合对话,何处有 应用模型自己的聊天模板,并记住较早的回合 在 WasmChat (send_stream, clear_history),目前尚未浮出水面 包装。

清理

await kjarni.close();

JavaScript垃圾收集器无法访问Wasm句柄,因此删除 引用泄露了权重。 close() 释放模型并停止worker。

需求

带有WebAssembly和模块工作器的浏览器:Chrome和Edge 80+, Firefox 114+, Safari 15 +。不需要WebGPU,推理在CPU上运行。

模型

.kjq 是一个单独的文件,包含配置,标记器和int8权重。这些都是 并托管在hug Face上,每个模型一个存储库,带有存储库 和文件名匹配:

const model = (name: string) =>
  `https://huggingface.co/olafuraron/${name}/resolve/main/${name}.kjq`;
通过名字大小它是做什么的
encoderall-MiniLM-L6-v2-q823 MB嵌入,相似度,搜索
rerankerms-marco-MiniLM-L-6-v2-q823 MBcross-encoder reranking
classifierdistilbert-sentiment-q868 MB积极/消极情绪
chatqwen05b-q8508 MB一个局部语言模型,块量化,所以它适合

hugs Face提供了允许的CORS,因此浏览器可以从 任何起源。对于生产,复制你需要的东西,并从你自己的来源提供: 您可以控制缓存,并且您的页面不依赖于其他人的正常运行时间。

只加载您使用的内容,然后连接 onProgress 对于一些可见的东西:它们是真实的 下载,沉默的一分钟读起来就像一个破碎的页面。

同样的引擎

Kjarni是几个包背后的一个Rust引擎。浏览器是一个目标;如果 您需要相同产品的服务器端一半:

制作自己的 .kjq

看到 格式指南. 任何bert族编码器, 交叉编码器,分类器或小解码器从拥抱脸转换与一个 脚本。

版本与发布记录

kjarni-wasm 共发布 22 个版本,首次发布于 2026/08/31;过去 12 个月发布了 22 个版本。

版本发布日期距今
0.4.3latest2026/11/041 天前
0.4.22026/11/031 天前
0.4.12026/11/032 天前
0.4.02026/11/013 天前
0.3.02026/11/014 天前
0.2.92026/10/314 天前

关于 kjarni-wasm 的常见问题

kjarni-wasm 是什么?

在你的网页中运行转换器模型:嵌入、分类、重新排序、语义搜索和web Worker中的聊天。与PyTorch相同的输出,没有服务器。

如何安装 kjarni-wasm?

在项目目录运行 npm install kjarni-wasm,或使用 pnpm add / yarn add / bun add。

kjarni-wasm 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

kjarni-wasm 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

kjarni-wasm 可以商用吗?

kjarni-wasm 使用 MIT OR Apache-2.0 许可。可在 MIT、Apache-2.0 中任选其一遵守。选择 MIT 时,宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

kjarni-wasm 还在维护吗?

最新版本 0.4.3 发布于 2026/11/04(1 天前);至今共发布 22 个版本,其中过去 12 个月发布了 22 个;首次发布于 2026/08/31。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。