如何在本地部署 Ollama 并使用 Qwen2.5 和 Nomic 嵌入模型。

一、Ollama 本地部署

Windows 系统部署

# 1. 下载安装包
访问 https://ollama.com/download/windows 下载安装

# 2. 安装后验证
ollama --version

# 3. 启动服务(Windows 自动启动)

Linux 系统部署

# 1. 一键安装脚本
curl -fsSL https://ollama.com/install.sh | sh

# 2. 启动服务
sudo systemctl start ollama
sudo systemctl enable ollama

# 3. 验证安装
ollama --version

二、下载和运行模型

1. 下载推理模型 (Qwen2.5)

# 下载不同版本的 Qwen2.5
ollama pull qwen2.5:7b        # 7B 参数版本
ollama pull qwen2.5:14b       # 14B 参数版本
ollama pull qwen2.5:0.5b      # 0.5B 参数版本(轻量级)

# 运行模型
ollama run qwen2.5:7b

2. 下载嵌入模型 (Nomic)

# 下载嵌入模型
ollama pull nomic-embed-text

# 验证模型列表
ollama list

三、通过 API 调用模型

Python 调用示例

# requirements.txt
# pip install requests

import requests
import json

class OllamaAPI:
    def __init__(self, base_url="http://localhost:11434"):
        self.base_url = base_url
    
    # 1. 生成文本
    def generate(self, model="qwen2.5:7b", prompt="", stream=False, **kwargs):
        """
        调用模型生成文本
        Args:
            model: 模型名称
            prompt: 输入提示
            stream: 是否流式输出
            **kwargs: 其他参数(temperature, top_p等)
        """
        url = f"{self.base_url}/api/generate"
        payload = {
            "model": model,
            "prompt": prompt,
            "stream": stream,
            **kwargs
        }
        
        if stream:
            return self._stream_response(url, payload)
        else:
            response = requests.post(url, json=payload)
            return response.json()
    
    # 2. 获取嵌入向量
    def embed(self, model="nomic-embed-text", prompt=""):
        """
        获取文本的嵌入向量
        """
        url = f"{self.base_url}/api/embed"
        payload = {
            "model": model,
            "prompt": prompt
        }
        response = requests.post(url, json=payload)
        return response.json()
    
    # 3. 对话聊天
    def chat(self, model="qwen2.5:7b", messages=None, stream=False):
        """
        对话式聊天
        """
        url = f"{self.base_url}/api/chat"
        payload = {
            "model": model,
            "messages": messages or [],
            "stream": stream
        }
        
        if stream:
            return self._stream_response(url, payload)
        else:
            response = requests.post(url, json=payload)
            return response.json()
    
    # 4. 流式处理
    def _stream_response(self, url, payload):
        response = requests.post(url, json=payload, stream=True)
        for line in response.iter_lines():
            if line:
                yield json.loads(line)
    
    # 5. 模型管理
    def list_models(self):
        """列出所有可用模型"""
        response = requests.get(f"{self.base_url}/api/tags")
        return response.json()
    
    def pull_model(self, model_name):
        """拉取新模型"""
        response = requests.post(
            f"{self.base_url}/api/pull",
            json={"name": model_name},
            stream=True
        )
        for line in response.iter_lines():
            if line:
                yield json.loads(line)

# 使用示例
if __name__ == "__main__":
    ollama = OllamaAPI()
    
    # 示例1: 文本生成
    print("=== 文本生成示例 ===")
    result = ollama.generate(
        model="qwen2.5:7b",
        prompt="请用Python写一个快速排序算法",
        temperature=0.7,
        max_tokens=500
    )
    print(f"响应: {result.get('response', '')}")
    
    # 示例2: 获取嵌入向量
    print("\n=== 嵌入向量示例 ===")
    embedding = ollama.embed(
        model="nomic-embed-text",
        prompt="这是一个测试文本"
    )
    print(f"嵌入向量维度: {len(embedding.get('embedding', []))}")
    
    # 示例3: 对话聊天
    print("\n=== 对话示例 ===")
    messages = [
        {"role": "user", "content": "你好,介绍一下你自己"}
    ]
    chat_result = ollama.chat(
        model="qwen2.5:7b",
        messages=messages
    )
    print(f"助手回复: {chat_result['message']['content']}")
    
    # 示例4: 流式生成
    print("\n=== 流式输出示例 ===")
    for chunk in ollama.generate(
        model="qwen2.5:7b",
        prompt="请写一首关于春天的诗",
        stream=True
    ):
        if 'response' in chunk:
            print(chunk['response'], end='', flush=True)

四、进阶使用示例

1. 批量处理嵌入

import numpy as np
from typing import List

class EmbeddingService:
    def __init__(self):
        self.ollama = OllamaAPI()
    
    def batch_embed(self, texts: List[str], model="nomic-embed-text"):
        """批量获取嵌入向量"""
        embeddings = []
        for text in texts:
            result = self.ollama.embed(model=model, prompt=text)
            embeddings.append(result.get('embedding', []))
        return np.array(embeddings)
    
    def similarity_search(self, query: str, documents: List[str]):
        """语义搜索示例"""
        # 获取查询嵌入
        query_embed = np.array(
            self.ollama.embed(prompt=query).get('embedding', [])
        )
        
        # 获取文档嵌入
        doc_embeds = self.batch_embed(documents)
        
        # 计算相似度
        similarities = np.dot(doc_embeds, query_embed) / (
            np.linalg.norm(doc_embeds, axis=1) * np.linalg.norm(query_embed)
        )
        
        # 排序并返回
        sorted_indices = np.argsort(similarities)[::-1]
        return [(documents[i], similarities[i]) for i in sorted_indices]

# 使用
emb_service = EmbeddingService()
documents = ["机器学习算法", "深度学习框架", "自然语言处理"]
results = emb_service.similarity_search("人工智能模型", documents)
print(f"搜索结果: {results}")

2. 对话历史管理

class ChatSession:
    def __init__(self, model="qwen2.5:7b"):
        self.ollama = OllamaAPI()
        self.model = model
        self.messages = []
        self.system_prompt = "你是一个有帮助的AI助手"
        
        if self.system_prompt:
            self.messages.append({
                "role": "system",
                "content": self.system_prompt
            })
    
    def add_message(self, role: str, content: str):
        self.messages.append({
            "role": role,
            "content": content
        })
    
    def chat(self, user_input: str, stream=False):
        self.add_message("user", user_input)
        
        if stream:
            return self._stream_chat()
        else:
            result = self.ollama.chat(
                model=self.model,
                messages=self.messages
            )
            response = result['message']['content']
            self.add_message("assistant", response)
            return response
    
    def _stream_chat(self):
        full_response = ""
        for chunk in self.ollama.chat(
            model=self.model,
            messages=self.messages,
            stream=True
        ):
            if 'message' in chunk:
                content = chunk['message']['content']
                full_response += content
                yield content
        
        self.add_message("assistant", full_response)
    
    def clear_history(self):
        self.messages = []
        if self.system_prompt:
            self.messages.append({
                "role": "system",
                "content": self.system_prompt
            })

# 使用示例
session = ChatSession()
print(session.chat("你好!"))
print(session.chat("你能帮我解决编程问题吗?"))

3. 配置参数详解

# 完整的生成参数配置
generation_config = {
    "model": "qwen2.5:7b",
    "prompt": "你的提示词",
    "stream": False,
    "temperature": 0.7,      # 随机性 (0-2)
    "top_p": 0.9,            # 核采样
    "top_k": 40,             # 从最可能的k个token中选择
    "num_predict": 512,      # 最大生成token数
    "repeat_penalty": 1.1,   # 重复惩罚
    "presence_penalty": 0.0, # 存在惩罚
    "frequency_penalty": 0.0,# 频率惩罚
    "seed": 42,              # 随机种子
}

五、FastAPI 集成示例

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional

app = FastAPI(title="Ollama API 网关")

# 数据模型
class GenerateRequest(BaseModel):
    model: str = "qwen2.5:7b"
    prompt: str
    temperature: Optional[float] = 0.7
    max_tokens: Optional[int] = 512

class ChatMessage(BaseModel):
    role: str
    content: str

class ChatRequest(BaseModel):
    model: str = "qwen2.5:7b"
    messages: List[ChatMessage]

# 初始化
ollama = OllamaAPI()

@app.post("/generate")
async def generate_text(request: GenerateRequest):
    try:
        result = ollama.generate(
            model=request.model,
            prompt=request.prompt,
            temperature=request.temperature,
            max_tokens=request.max_tokens
        )
        return {"response": result.get("response", "")}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.post("/chat")
async def chat_completion(request: ChatRequest):
    try:
        messages = [msg.dict() for msg in request.messages]
        result = ollama.chat(
            model=request.model,
            messages=messages
        )
        return {"message": result.get("message", {})}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.post("/embed")
async def get_embedding(text: str, model: str = "nomic-embed-text"):
    try:
        result = ollama.embed(model=model, prompt=text)
        return {"embedding": result.get("embedding", [])}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

# 启动命令
# uvicorn main:app --host 0.0.0.0 --port 8000

六、常用命令和技巧

1. Ollama 管理命令

# 查看已下载模型
ollama list

# 删除模型
ollama rm qwen2.5:7b

# 复制模型
ollama cp qwen2.5:7b my-custom-model

# 查看模型信息
ollama show qwen2.5:7b

# 修改模型配置
ollama create my-model -f Modelfile

2. Modelfile 自定义模型

# 创建自定义 Modelfile
FROM qwen2.5:7b

# 设置参数
PARAMETER temperature 0.8
PARAMETER top_p 0.9
PARAMETER num_predict 1024

# 设置系统提示
SYSTEM """你是专业的AI助手,回答要准确、有帮助。"""

# 构建自定义模型
# ollama create my-qwen -f ./Modelfile

七、性能优化建议

  1. 硬件要求

    • 7B模型:至少16GB RAM
    • 14B模型:至少32GB RAM
    • 使用GPU加速可大幅提升速度
  2. 启动参数优化

# 设置线程数
OLLAMA_NUM_PARALLEL=4 ollama serve

# GPU加速(如果有NVIDIA GPU)
ollama run qwen2.5:7b --gpu
  1. 内存管理
# 使用更小的模型处理简单任务
lightweight_model = "qwen2.5:0.5b"

这个部署方案可以让您在本地运行大语言模型,适用于开发测试、个人使用或内部工具开发。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐