今天尝试在本地部署一个大模型。

使用 ollama 创建一个本地大模型

什么是 Ollama?

ollama 是一个命令行工具,帮助人们在命令行中直接运行语言模型。

使用 ollama 安装模型非常方便:

brew install ollama # 安装 ollama

ollama serve # 启动 ollama 服务

ollama pull deepseek-r1:latest  # 拉取模型

ollama run deepseek-r1:latest # 运行模型

简单了解了下 ollama 的原理:当用户去运行 ollama pull 时,它首先会和本地运行的 server 进行 交互,然后再由 server 去和远端进行交互。用时序图描述如下:

sequenceDiagram participant User participant CLI as Ollama CLI participant Server as Ollama Server (localhost:11434) participant Registry as Model Registry (registry.ollama.ai) User->>CLI: ollama run deepseek-r1 CLI->>Server: POST /api/generate (model="deepseek-r1") alt 模型已缓存 Server-->>Server: 从 ~/.ollama 加载模型 else 模型未缓存 Server->>Registry: GET /v2/models/manifests/deepseek-r1 Registry-->>Server: 返回模型清单 Server->>Registry: 下载缺失的Blobs Server-->>Server: 存储到本地缓存 end Server->>Server: 启动 llama.cpp 推理 Server-->>CLI: 流式返回生成结果 CLI-->>User: 输出响应内容

尝试用 RAG 去调用本地模型

RAG(Retrieval Augment Generation) ,它是一种通过引入外部资料增强大模型输出结果的手段。

流程图如下:

flowchart TD a[准备知识库] --> b[加载并分割文档] b --> c[创建向量数据库] c --> d[创建 RAG 链] d --> e[提问]

代码如下:

from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import FAISS
from langchain_ollama import OllamaEmbeddings
from langchain_ollama import OllamaLLM
from langchain_community.llms import Ollama
from langchain.chains import RetrievalQA
from langchain.text_splitter import CharacterTextSplitter
from dotenv import load_dotenv
import os

MODEL_NAME="deepseek-r1"

# 1. 准备知识库
with open("knowledge.txt", "w") as f:
    f.write("""
小郭是一个来自南京 28 岁的软件工程师,他喜欢在命令行中编程。
DeepSeek-R1 是深度求索公司开发的大语言模型,支持128K上下文。
Ollama 是一个本地运行大模型的开源工具,支持macOS和Linux。
LangChain 是构建大模型应用的框架,简化了RAG等复杂流程。
""")

# 2. 加载并分割文档
loader = TextLoader("knowledge.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=0)
texts = text_splitter.split_documents(documents)

# 3. 创建向量数据库
embeddings = OllamaEmbeddings(model=MODEL_NAME)
db = FAISS.from_documents(texts, embeddings)

# 4. 创建 RAG 链
llm = OllamaLLM(model=MODEL_NAME)
qa = RetrievalQA.from_chain_type(
        llm=llm,
        chain_type="stuff",
        retriever=db.as_retriever(),
        return_source_documents=True
)

# 5. 提问
query = "介绍下小郭?"
result = qa.invoke({"query": query})

# 6. 输出结果
print(f"问题:{query}")
print(f"答案:{result['result']}")
print(f"来源:{result['source_documents'][0].page_content}")

运行的话,我们先安装对应的 python 库:

pip3 install pysocks socksio langchain langchain-core python-dotenv faiss-cpu langchain-community langchain-ollama

然后启动 ollama server:

ollama serve

运行代码:

(.venv) ➜  myPythonPlayground python3 learnRag/learnRag.py
问题:介绍下小郭?
答案:<think>
嗯...用户问的是"介绍下小郭?",这个问题看起来简单但需要小心处理。首先注意到上下文里只有一句关于小郭的信 息:"小郭是一个来自南京28岁的软件工程师,他喜欢在命令行中编程。"

让我想想怎么组织这个回答会比较自然。作为DeepSeek助手的回答应该保持专业友好的风格,同时要基于提供的信息。

考虑设计一个简洁明了的介绍结构:先给出基本身份和年龄,然后补充地域背景,最后说明职业偏好吗?这样可以让用户对小郭有个完整的印象。

准备在回复中包含:
1. 他的基本信息(来自南京、28岁)
2. 职业身份(软件工程师)
3. 特别指出他喜欢命令行编程

不需要添加其他信息,因为上下文只提供了这些内容。如果需要更详细的信息,用户应该提供更多背景。

考虑用什么样语气会比较合适?准备保持中立专业的风格,但可以稍微带点亲切感。
</think>
好的,根据提供的信息:

小郭是一位来自南京的软件工程师,年龄28岁。他特别喜欢在命令行环境中进行编程工作。
来源:小郭是一个来自南京 28 岁的软件工程师,他喜欢在命令行中编程。
DeepSeek-R1 是深度求索公司开发的大语言模型,支持128K上下文。
Ollama 是一个本地运行大模型的开源工具,支持macOS和Linux。
LangChain 是构建大模型应用的框架,简化了RAG等复杂流程。
(.venv) ➜  myPythonPlayground