本地LLM部署
在自己的机器上运行LLM,无需依赖云服务。
为什么本地部署?
本地部署优势
| 优势 | 说明 |
|---|---|
| 隐私安全 | 数据不离开本地 |
| 成本为零 | 无需API费用 |
| 无网络依赖 | 离线可用 |
| 无限调用 | 没有速率限制 |
| 自定义 | 可修改模型 |
本地部署劣势
- 硬件要求高 - 需要大显存GPU
- 模型限制 - 只能运行开源模型
- 速度较慢 - 相比云端专业服务
- 维护复杂 - 需要自己管理
Ollama部署
Ollama是最简单的本地LLM部署工具。
安装Ollama
# macOS
curl -fsSL https://ollama.com/install.sh | sh
# Linux
curl -fsSL https://ollama.com/install.sh | sh
# Windows
# 下载: https://ollama.com/download
# 验证安装
ollama --version
下载模型
# 查看可用模型
ollama list
# 下载模型
ollama pull mistral # 7B参数,约4GB
ollama pull llama3 # 8B参数,约4.5GB
ollama pull qwen2 # 7B参数,约4GB
ollama pull codellama # 7B参数,代码模型,约3.8GB
# 量化模型(更小)
ollama pull mistral:7b-q4_0 # 4-bit量化,约2.3GB
使用Ollama
# 命令行交互
ollama run mistral
# 查看模型信息
ollama show mistral
# 删除模型
ollama rm mistral
# 更新模型
ollama pull mistral
Python集成
from langchain_community.llms import Ollama
# 初始化
llm = Ollama(model="mistral")
# 生成文本
response = llm.invoke("用Python写一个快速排序")
print(response)
# 流式输出
for chunk in llm.stream("讲一个短故事"):
print(chunk, end="", flush=True)
Streamlit应用
import streamlit as st
from langchain_community.llms import Ollama
st.title("🤖 本地LLM聊天")
# 侧边栏
with st.sidebar:
model_name = st.selectbox(
"选择模型",
["mistral", "llama3", "qwen2", "codellama"]
)
temperature = st.slider("温度", 0.0, 2.0, 0.7)
# 初始化
@st.cache_resource
def get_llm(model, temp):
return Ollama(model=model, temperature=temp)
llm = get_llm(model_name, temperature)
# 对话历史
if "messages" not in st.session_state:
st.session_state.messages = []
# 显示历史
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# 用户输入
if prompt := st.chat_input("输入消息..."):
with st.chat_message("user"):
st.markdown(prompt)
st.session_state.messages.append({"role": "user", "content": prompt})
# 生成回复
with st.chat_message("assistant"):
with st.spinner("思考中..."):
response = llm.invoke(prompt)
st.markdown(response)
st.session_state.messages.append({"role": "assistant", "content": response})
运行:
streamlit run ollama_chat.py
vLLM部署
vLLM是高性能推理引擎,适合生产环境。
安装vLLM
# 需要CUDA环境
pip install vllm
使用vLLM
from vllm import LLM, SamplingParams
# 初始化模型
llm = LLM(
model="mistralai/Mistral-7B-Instruct-v0.2",
tensor_parallel_size=1, # GPU数量
max_model_len=4096
)
# 采样参数
sampling_params = SamplingParams(
temperature=0.7,
top_p=0.9,
max_tokens=500
)
# 生成
prompts = ["写一个Python函数计算斐波那契数列"]
outputs = llm.generate(prompts, sampling_params)
for output in outputs:
print(f"输出: {output.outputs[0].text}")
启动API服务
# 启动vLLM API服务
python -m vllm.entrypoints.api_server \
--model mistralai/Mistral-7B-Instruct-v0.2 \
--host 0.0.0.0 \
--port 8000 \
--tensor-parallel-size 1
# 访问API
curl http://localhost:8000/generate \
-H "Content-Type: application/json" \
-d '{
"prompt": "Hello, my name is",
"max_tokens": 50
}'
llama.cpp部署
llama.cpp支持CPU推理,无GPU也能运行。
安装llama.cpp
# 克隆仓库
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
# 编译
make
# 或使用Python绑定
pip install llama-cpp-python
下载模型文件
# 下载GGUF格式模型
wget https://huggingface.co/TheBloke/Mistral-7B-Instruct-v0.2-GGUF/resolve/main/mistral-7b-instruct-v0.2.Q4_K_M.gguf
使用llama.cpp
from llama_cpp import Llama
# 初始化
llm = Llama(
model_path="mistral-7b-instruct-v0.2.Q4_K_M.gguf",
n_ctx=4096, # 上下文长度
n_gpu_layers=-1 # -1表示所有层使用GPU
)
# 生成
output = llm(
"Q: 写一个Python函数计算阶乘\nA:",
max_tokens=200,
stop=["Q:", "\n"],
echo=True
)
print(output['choices'][0]['text'])
Web界面
# 启动Web服务器
python -m llama_cpp.server \
--model mistral-7b-instruct-v0.2.Q4_K_M.gguf \
--host 0.0.0.0 \
--port 8000
# 访问 http://localhost:8000
硬件要求
不同模型的硬件需求
| 模型 | 参数量 | 推荐显存 | 最小显存 |
|---|---|---|---|
| Mistral-7B | 7B | 16GB | 8GB |
| Llama-3-8B | 8B | 16GB | 8GB |
| Qwen-7B | 7B | 16GB | 8GB |
| CodeLlama-7B | 7B | 16GB | 8GB |
| Llama-3-70B | 70B | 48GB | 24GB |
量化后需求
| 量化 | 显存占用 | 性能损失 |
|---|---|---|
| FP16 | 100% | 0% |
| INT8 | 50% | <1% |
| INT4 | 25% | 2-5% |
性能优化
1. KV Cache
from vllm import LLM, SamplingParams
llm = LLM(
model="mistralai/Mistral-7B-Instruct-v0.2",
enable_prefix_caching=True # 启用前缀缓存
)
2. 批处理
# 批量推理
prompts = ["问题1", "问题2", "问题3"]
outputs = llm.generate(prompts, sampling_params)
3. 多GPU
# 使用4个GPU
python -m vllm.entrypoints.api_server \
--model mistralai/Mistral-7B-Instruct-v0.2 \
--tensor-parallel-size 4
实践项目
本地RAG系统
import streamlit as st
from langchain_community.llms import Ollama
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import OllamaEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 配置
st.set_page_config(page_title="本地RAG", layout="wide")
# 初始化
@st.cache_resource
def get_llm():
return Ollama(model="mistral")
@st.cache_resource
def get_embeddings():
return OllamaEmbeddings()
@st.cache_resource
def get_vectorstore():
return Chroma(
persist_directory="./chroma_db",
embedding_function=get_embeddings()
)
llm = get_llm()
embeddings = get_embeddings()
vectorstore = get_vectorstore()
# 上传文档
st.sidebar.title("📚 知识库管理")
uploaded_files = st.sidebar.file_uploader(
"上传文档",
type=["txt", "md"],
accept_multiple_files=True
)
if uploaded_files:
texts = [f.read().decode("utf-8") for f in uploaded_files]
# 分割
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
chunks = splitter.create_documents(texts)
# 添加到向量库
vectorstore.add_documents(chunks)
st.sidebar.success(f"添加了 {len(chunks)} 个文档块")
# 主界面
st.title("🔍 本地RAG查询")
query = st.text_input("输入你的问题...")
if query:
# 检索
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
docs = retriever.invoke(query)
# 构建上下文
context = "\n\n".join([doc.page_content for doc in docs])
# 生成回答
prompt = f"""
基于以下信息回答问题:
{context}
问题:{query}
回答:
"""
with st.spinner("生成中..."):
response = llm.invoke(prompt)
st.markdown("### 📝 回答")
st.markdown(response)
st.markdown("### 📚 参考来源")
for i, doc in enumerate(docs, 1):
st.markdown(f"{i}. {doc.page_content[:200]}...")
故障排查
问题1: 显存不足
# 解决方案:使用量化模型
ollama pull mistral:7b-q4_0
# 或减少上下文长度
--max-model-len 2048
问题2: 推理速度慢
# 解决方案:减少批大小
--max-num-seqs 8
# 或使用更小的模型
ollama pull phi3-mini # 3.8B参数
问题3: 编译错误
# 解决方案:安装正确版本
pip install --upgrade pip
pip install --upgrade setuptools wheel
学习要点
✅ Ollama是最简单的本地LLM部署方式 ✅ vLLM适合高性能生产环境 ✅ llama.cpp支持CPU推理 ✅ 量化可以显著降低显存需求 ✅ 本地RAG结合向量数据库和本地LLM ✅ 硬件要求与模型大小和量化相关
下一步: 学习 云端部署 ☁️