# ollama的发展历程

# 项目启动与早期版本(2023 年中期)

# 背景:

  • Meta 发布 Llama 2(2023 年 7 月)后,开源 LLM 生态快速发展,但本地部署门槛较高Ollama 应运而生,目标是降低用户运行 LLM 的复杂性

# 首次发布:

2023 年 8 月,Ollama 推出初始版本,支持 Llama 2 系列模型。用户可通过命令行快速下载和运行模型,无需复杂配置。

# 核心功能:

  • 一键安装(支持 macOS 和 Linux)。
  • 自动处理模型依赖和硬件加速(如 Apple Silicon 芯片的 GPU 支持)。

# 功能扩展与生态建设(2023 年末 - 2024 年初)

# 模型支持扩展:

  • 新增对 Mistral、Code Llama、Gemma 等模型的支持,覆盖更多应用场景(如代码生成、多语言任务)。
  • 推出模型库(Model Library)​,用户可直接下载预配置模型。

# 开发者工具增强:

  • 提供 REST API 和 Python/JavaScript 库,支持将 Ollama 集成到第三方应用。
  • 引入类似 Docker 的 Modelfile,允许自定义模型配置。

# 跨平台支持:

  • 2024 年初推出 Windows 预览版,实现 macOS、Linux、Windows 全平台覆盖。

# 性能优化与社区爆发(2024 年)

# 硬件加速升级:

  • 优化 NVIDIA/AMD GPU 支持,提升推理速度。
  • 针对 Apple Silicon 芯片(M1/M2)的 Metal 框架深度适配。

# 社区增长:

  • GitHub Star 数突破 70k(截至 2024 年中),成为最活跃的 LLM 工具之一。
  • 出现大量第三方插件(如 VS Code 扩展、ChatGPT 风格 Web UI)。

# 企业级功能

  • 推出高级功能如多用户管理、模型监控,吸引企业用户。

# 总结

  • Ollama 的快速发展反映了本地化 LLM 部署的强烈需求,其开源、轻量化的设计使其成为个人开发者与企业探索 AI 的理想入口。随着模型硬件的持续进步,Ollama 或将成为去中心化 AI 生态的关键基础设施

# ollama部署实践

# 有网环境安装ollama

 curl -fsSL https://ollama.com/install.sh | sh
 
 # 运行模型
 ollama run deepseek-r1:1.5b
 
 # 下载模型
 ollama pull deepseek-r1:1.5b

# 本地模型备注

# 无网环境安装ollama

# 从有网环境下载,并上传到无网环境: curl https://ollama.com/download/ollama-linux-amd64.tgz
tar -zxvf ollama-linux-amd64.tgz

  • 创建ollama.service服务,vim /etc/systemd/system/ollama.service
[Unit]
Description=Ollama Service
After=network-online.target

[Service]
# 此处配置 ollama的bin地址即命令
ExecStart=/home/user/ollama/bin/ollama serve
# 此处配置启动ollama的用户
User=user
Group=user
Restart=always
RestartSec=3
Environment="PATH=$PATH"

# 此处配置模型地址,注意, 启动ollama的用户,必须有这个地址的读写权限
Environment="OLLAMA_MODELS=/data/ollama-models01/models"
Environment="OLLAMA_HOST=0.0.0.0:11434"

# 当前环境所使用的CUDA设备
Environment="CUDA_VISIBLE_DEVICES=0,1,2,3"
# 是否将模型负载均衡在多卡环境
Environment="OLLAMA_SCHED_SPREAD=1"
# 模型是否常驻现存,否则闲时会自动卸载
Environment="OLLAMA_KEEP_ALIVE=-1"
# ollama的并发连接数
Environment="OLLAMA_NUM_PARALLEL=64"
# 是否开启flash attention 计算加速
Environment="OLLAMA_FLASH_ATTENTION=1"

[Install]
WantedBy=default.target
  • 启动ollama服务
systemctl daemon-reload
systemctl enable ollama
systemctl start ollama

# ollama的restapi流式代理

  • ollama的流式响应头,使用的nxjson格式,与主流的text/event-stream格式有区别,会导致常规流式框架解析失败
  • 使用其客户端代理包装,可较小代价解决该问题
import express from 'express';
import {Ollama} from 'ollama'

// 从环境变量读取,设置默认值
const ollamaHost = process.env.OLLAMA_HOST || 'http://127.0.0.1:11434';
const port = process.env.PORT || 3501;

//OLLAMA_HOST="http://home.automannn.cn:9086" PORT=3500 node server.js

const ollama = new Ollama({
    host: ollamaHost,
})
const app = express();

async function stream_chat(reqData,req, res) {
    // 设置 SSE 相关头部
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');

    const response = await ollama.chat({ model: reqData.model, messages: reqData.messages, stream: true ,options:reqData.options})
    for await (const part of response) {
        res.write(`data: ${JSON.stringify(part)}\n\n`)
        if (part.done) {
            res.end();
        }
    }

    // 客户端断开连接时清理
    req.on('close', () => {
        console.log('客户端断开连接');
    });
}

async function block(reqData, req, res) {
    const response = await ollama.chat({
        model: reqData.model,
        messages: reqData.messages,
        stream:false,
        options:reqData.options
    })
    res.json(response);
}


// 启用 JSON 请求体解析(关键配置)
app.use(express.json()); // 内置中间件,支持 application/json
// 允许跨域(可选,根据需求)
app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    next();
});

// SSE 路由
app.post('/api/chat', (req, res) => {

    // 1. 验证请求数据格式
    if (!req.body || Object.keys(req.body).length === 0) {
        return res.status(400).json({error: '请求体不能为空'});
    }

    // 2. 获取结构化数据
    const reqData = req.body;
    const {
        model = '',  // 默认值
        messages,
        stream = false,
        options = {}
    } = reqData;

    // 3. 必需字段校验
    if (!messages || !Array.isArray(messages)) {
        return res.status(422).json({
            error: 'messages 必须是有效数组'
        });
    }

    if (!model) {
        return res.status(422).json({
            error: 'model 不能为空'
        });
    }

    if (stream) {
        stream_chat(reqData,req, res)
    } else {
        block(reqData, req, res)
    }
});
app.listen(port, () => {
    console.log(`SSE 服务器运行在 http://localhost:${port}`);
});
  • 将该模型制作为docker,方便调用
# base image
FROM 192.168.10.7:20080/library/node:20.11-alpine3.19 AS base
LABEL maintainer="chenkh"

#使用阿里云的apk镜像源
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

# 时区配置包
RUN apk add --no-cache tzdata


# install packages
FROM base AS packages

WORKDIR /app

COPY package.json .
#COPY yarn.lock .

# 使用yarn作为包管理工具
RUN yarn install --frozen-lockfile --registry https://registry.npmmirror.com/

RUN yarn install --frozen-lockfile

# build resources
FROM base AS builder
WORKDIR /app
COPY --from=packages /app .
COPY . .

# production stage
FROM base AS production

ENV OLLAMA_HOST=${OLLAMA_HOST:-http://127.0.0.1:11434}
ENV PORT=${PORT:-3500}
# set timezone
ENV TZ=UTC
RUN ln -s /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo ${TZ} > /etc/timezone

WORKDIR /app
COPY --from=builder /app ./

EXPOSE ${PORT}

CMD ["node", "server.js"]

#docker run -d -p 3500:3500 -e PORT=3500 -e OLLAMA_HOST=http://172.17.0.1:11434 ollama-client-proxy

# ollama模型说明

# 模型量化的说明

  • 参考文档: LLM量化综合指南(8bits/4bits) (opens new window)
  • 模型量化(Quantization)是一种用于通过修改权重的精度来减小大型神经网络(包括大型语言模型)大小的技术。LLM量化之所以能够实现,是因为经验结果表明,虽然与神经网络训练和推理相关的一些操作必须利用高精度,但在某些情况下,可以使用明显较低的精度(例如INT8)来减小模型的总体大小,从而允许其使用功能较弱的硬件来运行,同时其能力和准确性可接受地降低
  • 发现不使用4字节FP32精度转而使用2字节BF16/FP16半精度可以获得几乎相同的推理结果,同时模型大小会减半。促使我们想进一步削减内存,如果再从2字节半精度转成仅1字节的8bits数据类型,甚至4bits类型呢?实际上,对于大模型最常见的就是8bits量化(FP8/INT8)和4bits量化(FP4/NF4/INT4)
  • 模型一个典型的场景是将权重从FP16(16位浮点)减少到INT4(4位整数)。同时,在内存中传输时,也显著降低了带宽占用。这允许模型在更便宜的硬件上或以更高的速度运行。通过降低权重的精度,LLM的整体质量也会受到一些影响
  • 研究表明,这种影响因所使用的技术而异,较大的模型受到精度变化的影响较小更大的型号(超过70B)即使转换为4bits也能保持其性能。一些技术,如NF4,表明对其性能没有影响。因此,对于这些较大的型号,4bits似乎是性能和大小/速度之间的最佳折衷,而对于较小的型号,8bits量化可能更好
  • 量化算法可以分为两种:
    • 训练后量化(PTQ):将已经训练好的模型的权重转换为较低的精度,而无需任何再训练。尽管PTQ简单易实现,但由于权重值的精度损失,它可能会略微降低模型的性能。
    • 量化感知训练(QAT):与PTQ不同,QAT在训练阶段集成了权重转换过程。这通常不会明显降低模型性能,但对计算的要求更高。QLoRA就是一种高度使用QAT的技术。

# ollama量化模型

  • Ollama 下载的模型默认情况下都是经过量化的。具体来说,Ollama 提供了两种主要的量化方案:

    • 4 位整数精度 (INT4):这是默认的量化方案,这是一种更激进的量化方案,可以将模型的大小和推理所需的显存减少约 8 倍。但是,INT4 量化可能会对模型的准确性造成更大的影响。
    • 8 位浮点精度 (FP8):它可以将模型的大小和推理所需的显存减少约 4 倍。在大多数情况下,FP8 量化对模型的准确性影响很小。
  • 参考文档: Ollama 默认下载量化后模型 (opens new window)

# ollama加载未经量化的模型(了解即可)

# vim Modelfile
# 在 huggingface 下载指定的模型,并使用llama进行转换并量化后, 使用导入模型的方式在 Ollama 上运行
FROM ./mistral-7b-v0.1.Q4_0.gguf
TEMPLATE "[INST] {{ .Prompt }} [/INST]"

# 创建模型
ollama create example -f Modelfile

ollama run example "What is your favourite condiment?"