<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Bge-M3 - tag - OnClickListener2048 Study Notes</title><link>https://onclicklistener2048.github.io/tags/bge-m3/</link><description>Bge-M3 - tag - OnClickListener2048 Study Notes</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Sun, 09 Aug 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://onclicklistener2048.github.io/tags/bge-m3/" rel="self" type="application/rss+xml"/><item><title>从零手写一个 RAG 系统（实战学习笔记）</title><link>https://onclicklistener2048.github.io/posts/rag-from-scratch/</link><pubDate>Sun, 09 Aug 2026 00:00:00 +0800</pubDate><author>OnClickListener</author><guid>https://onclicklistener2048.github.io/posts/rag-from-scratch/</guid><description><![CDATA[<p>去年写过一篇 <a href="/posts/rag-concept/" rel="">RAG 概念科普</a>，这次不一样：<strong>在本地从零手写了一个最小 RAG 系统</strong>。不引入 LlamaIndex、LangChain 的检索部分，链路里的每一环——分块、embedding 调用、向量存取、相似度检索——都是自己写的。</p>
<p>这么做的原因很简单：目标是<strong>学习</strong>，而只有手写一遍，才能回答那些框架文档不会告诉你的问题：</p>
<ul>
<li>embedding 到底返回了什么？数值长什么样？</li>
<li>为什么&quot;苹果&quot;和&quot;汽车&quot;的相似度也有 0.53？</li>
<li>检索为什么不能只看 top-k，还要看分数？</li>
<li>全量遍历检索在什么时候会撑不住？</li>
</ul>
<p>这篇文章是完整的过程记录，包含所有实验结果和踩坑经历。</p>
<h2 id="一环境老显卡上的-ollama">一、环境：老显卡上的 Ollama</h2>
<p>选型结论：本地模型 <code>bge-m3</code>（1024 维，中文效果好，离线免费），通过 Ollama 提供 OpenAI 兼容的 <code>/v1/embeddings</code> 接口。</p>
<p>踩了个大坑：本机是 GTX 1060（Pascal 架构，太老），新版 Ollama 的 CUDA 内核一加载就崩：</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-">
        <span class="code-title"><i class="arrow fas fa-angle-right fa-fw" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title=""><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><pre tabindex="0"><code>llama-server process has terminated:
CUDA error: the provided PTX was compiled with an unsupported toolchain</code></pre></div>
<p>排查过程值得记录（每个变量都试过）：</p>
<table>
  <thead>
      <tr>
          <th>尝试</th>
          <th>结果</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>OLLAMA_GPU_LAYERS=0</code>（0 层上 GPU）</td>
          <td>❌ 无效，CUDA 仍初始化</td>
      </tr>
      <tr>
          <td><code>OLLAMA_VISIBLE_DEVICES=&quot;&quot;</code>（屏蔽 GPU）</td>
          <td>❌ 无效，空值被当成&quot;全部可见&quot;</td>
      </tr>
      <tr>
          <td><code>OLLAMA_LLM_LIBRARY=cpu</code>（强制 CPU 推理库）</td>
          <td>✅ 生效</td>
      </tr>
  </tbody>
</table>
<p>经验：<strong>embedding 是纯推理（无生成），小模型跑 CPU 完全够用</strong>。12 个分块建索引总共才 2 秒。以后遇到老显卡 + 新 CUDA 内核的组合，<code>OLLAMA_LLM_LIBRARY=cpu</code> 是第一选择。</p>]]></description></item></channel></rss>