当你提问时发生了什么
导入和提问共用同一条流程,只有最后一步允许联网。
- 导入
- pdf · docx · pptx · http每种格式走自己的解析器 —— pdfjs-dist、mammoth、officeparser、turndown —— 所以标题、页面边界和幻灯片结构在格式支持它们时都会保留。
- 切分
- ~500 字符 · 50 重叠文本变成片段,每个片段记录它在抽取文本中的起止偏移。这一步让后面的引用成为可能。
- 嵌入
- 在进程内片段在应用内部变成向量,使用内置的本地后端。嵌入过程不向任何地方发送数据。
- 检索
- sqlite-vec · 按笔记本你的问题以同样的方式嵌入,并只与该笔记本的向量匹配。两本笔记本从不共享排序。
- 回答
- 你的模型,你的端点检索到的片段和问题会发送到你配置的模型连接。回答返回时带着指向产生它的片段的引用。
嵌入模型就在这个进程里运行
这一步通常需要一个服务。在这里它是一个库。
- 模型
- Xenova/multilingual-e5-small一个多语言句子嵌入模型,所以一种语言的问题可以找到另一种语言的片段。
- 运行时
- ONNX,进程内它在应用内部运行。没有要启动的服务,也没有要运行的容器。
- 版本
- 锁定到一个提交确切的模型版本被固定。上游的改动无法悄悄重新定义你知识库所依据的向量。
- 量化
- q8量化权重:下载更小、常驻占用更小,代价是一点点精度。
- 维度
- 384每个向量的宽度。
- 前缀
- query: / passage:E5 在训练时为两侧各自使用指令前缀。问题和片段使用不同的前缀,这就是为什么一个问题能找到与它几乎没有共同词的片段。
- 下载
- 一次,按需第一次需要时获取,之后缓存到磁盘。
- 推理时网络
- 已禁用远程模型加载被关闭,所以一次检索不可能悄悄联网。
一本笔记本一张向量表
嵌入模型定义了一个空间,来自两个不同空间的向量不可比较 —— 它们之间的余弦相似度只是一个数字,不是含义。换模型、换版本、换量化或池化方式,你就得到了另一个空间。
KnowNote 从后端、模型、版本、dtype、池化、归一化、前缀和维度推导出一个身份标识,并给每本笔记本它自己的向量表,携带它自己的宽度。来自不同空间的向量永远不会被比较,因为根本没有比较发生的地方。这是结构上的保证,而不是一个需要记得运行的检查。
你的磁盘上会有什么
- 文档
- 你的原件,不被改动导入只是读取文件。它不会移动、改写或上传它。
- 抽取文本与片段
- SQLite一个本地数据库保存抽取的文本、片段和它们的偏移。
- 向量
- sqlite-vec存在同一个数据库里,放在属于该笔记本的表里。
- 笔记
- 同一个数据库笔记本、笔记及其结构就和其余数据放在一起。
- 模型文件
- 一个缓存目录下载一次,跨笔记本复用。
还有什么会用到网络
“本地”只有在具体说明例外时,才是一个有用的词。
- 提问
- 到你的端点检索到的片段和你的问题会发送到你配置的模型连接。如果那是本地服务器,就完全没有数据离开这台机器。
- 导入与检索
- 无解析、切分、嵌入和检索全部在本地完成。
- 首次嵌入
- 一次下载模型只获取一次。之后检索可在断网状态下工作。