Hachi 是一个完全自托管的图像搜索引擎,针对个人分布式数据(如本地硬盘、Android MTP、云存储)设计,仅提取元数据和 ML embeddings 而不复制原始文件,支持文本/图像查询的语义相似检索。其创新在于 Nim/Python 混合后端、列式元索引与分片向量索引,实现低资源下高效搜索,适用于隐私敏感场景。
Hachi 的索引从路径(如 file://photos 或 mtp://Android)异步批处理图像:提取 EXIF(日期、位置)、尺寸、哈希;CLIP ViT-B/32 生成 512 维全局嵌入,RetinaFace 输出人脸边界框/地标/128 维嵌入。元数据存入 Nim 实现的单线程列式 Meta-Index(支持 string/int32/float32/bool/array[string],JSON 接口),向量分片为 numpy float32 张量(默认 2048x512)。
观点:分片机制调节 RAM(shard_size ∝ RAM/ (dim*4bytes)),查询逐分片 np.dot 计算余弦相似(BLAS 加速达 90% 峰值),融合 top-K。作者强调:“meta-data indexing engine, coupled with vector-search engines for semantic search。”
参数配置:
- 嵌入管道:预处理融合内核(Nim):resize(224x224)、RGB→BGR、ImageNet 归一化(mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225])。
- 分片参数:size=2048(低端 1024,高 RAM 4096);加载阈值:RAM<4GB 时异步预载。
- 人脸处理:HOG 过滤(阈值0.6 排除墨镜/模糊),聚类阈值0.75(主嵌入顺序比较,非穷举)。
测试:i5-8300H/8GB 索引 50万 Pexels 图像(180GB)数小时,查询<100ms,支持取消/ETA。
相似检索与多信号融合
查询输入文本/图像→CLIP 嵌入,逐分片 matmul top-20/shard→全局 top-100,阈值过滤(CLIP 0.3,人脸0.6)。Meta-Index 后滤(如 date>2020 AND personML=cluster1),支持分页/递归精炼(“beach person:Alice size>1MB”)。
观点:避免 ANN 压缩损失(如 HNSW 质心偏差),直用原始嵌入高召回;未来计划产品量化(128bit/emb)+线性微调(任务特定,如植物区分)。
融合权重(可调 API):
| 信号 |
默认权重 |
调优建议 |
| 语义嵌入 |
0.6 |
创意搜索↑ |
| 元数据 |
0.3 |
EXIF 优先↑ |
| 人脸 |
0.1 |
肖像集↑ |
监控点:API /status(进度、ETA、RAM);阈值警报<0.2 重聚类。
部署与调优清单
- 环境:Python3(numpy/regex/markupsafe/requests?);Nim 1.6+;Zig-cc 跨编译 Linux libc2.27;OneDNN(ML 加速)。
- 安装:git clone https://github.com/eagledot/hachi;nim c src/meta.nim;python backend.py。
- 索引:POST /index {path: "/photos", mtpscan: true};并行线程饱和,I/O 融合减 50% 开销。
- 性能调优:
- float16(ARM v8/AVX512):加速 1.5x,阈值精度-5%。
- 分布式:基准 2048x2048 matmul 延迟,分片迁移手机/SBC。
- 回滚:重置 immutable 字段(personML),用户编辑 person。
- 风险限:聚类顺序敏感(首索引 1k 图像稳定);ViT-B/32 占位,换 RN50 精度+10%;调试 GDB 多线程。
单机基准:100万图像,索引/天 20万,查询 50ms。扩展 MTP/Google Drive,支持 10M 规模。
Hachi 诠释极简主义:3 Python 依赖、无 Docker,易 hack。未来视频/文本模态共享管道。
(字数:1024)
资料来源:
- eagledot.xyz/hachi.md.html:“We never intend to duplicate the original-data”。
- GitHub eagledot/hachi。