# 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
# 本地模型备注
- 本地模型的默认位置:
/usr/share/ollama/.ollama/models
- 本地模型直接压缩拷贝,可进行不同环境的迁移。
- 参考文档:ollama模型离线迁移/复制 (opens new window)
# 无网环境安装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 /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 /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加载未经量化的模型(了解即可)
- 参考文档: Ollama 导入模型指南 (opens new window)
- 将huggingface模型转换成ollama模型: 如何用hugging face hub一键下载模型并将模型转换为gguf格式(支持自定义量化) (opens new window)
# 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?"