Ollama的底层实现原理分析
一、背景
Ollama我们可以很方便的对DeepSeek等开源大模型进行部署,几条命令便能部署一个本地大模型服务,降低了非专业大模型开发者的门槛。
我们从中可以看到类似Docker的影子,ollama run 、ollama list等等,拉取对应大模型镜像,通过镜像运行"大模型容器",并且还提供管理这些"大模型容器"的API接口,方便我们进行大模型对话、停止容器、运行容器、重启容器等等。
那我们来看下Ollama到底是怎么将大模型运行起来的?是底层使用Docker做了一层嵌套包装呢? Ollama的大模型镜像怎么制作? Modelfile和Dockerfile相似之处等神秘面纱
二、分析过程
1、Ollama是开源项目
首先我们知道Ollama是开源项目,项目地址在github进行开源:
开源地址: https://github.com/ollama/ollama
开源意味着代码都是公之于众的,那么"神秘面纱"自然也不是过于神秘,我们可以通过源代码去分析整个实现原理
2、项目使用Go语言实现
进入Ollama的开源仓库,我们发现,原来Ollama这个项目整体是使用Go语言进行开发实现的。docker、k8s这些云原生的组件,很多都使用Go进行开发, 因为其易并发编程、资源低消耗、轻量级、跨平台性好,深受广大开发者喜爱。 Ollama自然选中了Go
3、llama.cpp项目
我们假设,没有使用Ollama运行大模型。那么直接原生运行大模型,该怎么办? 这就不得不提到llama.cpp这个项目.
项目地址: https://github.com/ggml-org/llama.cpp
lama.cpp 项目主要解决了在本地设备(尤其是资源受限的设备)上高效运行 Llama 模型的问题,具体体现在以下几个方面:
- 设备端推理:Llama 是 Meta 公司开发的大型语言模型,原始的 Llama 模型运行需要强大的计算资源,如 GPU 集群等。而 llama.cpp 项目通过优化代码实现,使得 Llama 模型可以在普通的 CPU 设备上(如个人电脑、移动设备等)运行。这对于那些无法访问大规模计算资源的用户或场景(如没有 GPU 支持的个人电脑、边缘设备等)非常有帮助,使得用户可以在本地设备上进行模型推理,而不需要依赖云端服务,增强了模型使用的灵活性和隐私性。
- 降低计算资源需求:该项目对 Llama 模型的计算过程进行了优化,减少了内存占用和计算量。通过采用量化技术(如将模型参数从高精度数据类型转换为低精度数据类型),在一定程度上牺牲模型的精度来换取计算资源的大幅降低,从而能够在资源有限的设备上顺利运行模型。例如,在一些内存较小的设备上,也能够加载和运行 Llama 模型的较小版本。
- 促进模型的研究和应用:llama.cpp 使得更多的研究人员和开发者能够在本地方便地对 Llama 模型进行研究、实验和应用开发。它为自然语言处理领域的研究提供了一个更易于访问和使用的平台,加速了相关研究的进展。同时,也为一些基于 Llama 模型的应用开发提供了可能,如本地的文本生成工具、智能助手等,促进了语言模型在不同领域的应用和创新。
- 提升模型的可定制性:由于是在本地运行,开发者可以根据自己的需求对模型进行定制和修改,如调整模型的参数、添加特定的功能模块等。这种可定制性使得 llama.cpp 能够更好地满足不同用户和应用场景的需求,而不像使用云端服务那样受到一定的限制。
llama.cpp可以友好的对GGUF大模型文件格式进行运行,只需要提供GGUF文件,一条命令就能将这个模型运行起来。 同时llama.cpp提供了c++的SDK库,c++可以通过llama.cpp的API就能操作大模型。
4、llama.cpp运行大模型过程
1、Hugging Face下载对应大模型的GGUF文件
国内镜像地址: https://hf-mirror.com/
https://hf-mirror.com/unsloth/DeepSeek-R1-Distill-Qwen-1.5B-GGUF/tree/main
我下载了一个DeepSeek最小模型1.5b做本地测试
2、docker运行llama.cpp容器,进入容器启动大模型
docker-compose.yml文件:
version: "3"
services:
llama:
image: yusiwen/llama.cpp
volumes:
- ./models/:/models/
entrypoint: ["tail", "-f", "/dev/null"]
modes目录存放模型文件: DeepSeek-R1-Distill-Qwen-1.5B-Q2_K.gguf
docker-compose up -d #运行容器
#进入容器执行, 就可以进行模型对话
docker-compose exec llama bash
./llama-cli -m /models/DeepSeek-R1-Distill-Qwen-1.5B-Q2_K.gguf

5、Ollama和llama的关系
Ollama 在 llama.cpp 的基础上进行了更高层次的封装和功能拓展,以下是具体说明:
- llama.cpp 是基础:llama.cpp 是一个用 C/C++ 实现的推理框架,用于加载和运行 LLaMA 等大型语言模型13。它为在各种硬件平台上高效运行大模型提供了底层支持,实现了量化等功能以降低模型运行对资源的需求,让 LLaMA 模型能在如个人电脑 CPU 甚至手机、树莓派等设备上运行3。比如在谷歌 Pixel5 手机上能以 1token/s 的速度运行 7B 参数模型,在 M2 芯片的 Macbook Pro 上使用 7B 参数模型的速度约为 16token/s3。
- Ollama 基于 llama.cpp 拓展:Ollama 利用了 llama.cpp 提供的底层能力,如量化等。但它不是对 llama.cpp 的简单复用,而是在此基础上进行了功能的拓展和封装,提供了更友好的用户界面和更便捷的操作方式13。比如,用户使用 llama.cpp 时,需要获取模型权重、克隆项目代码、执行模型量化等一系列复杂操作,而 Ollama 简化了这些流程,通过简单的安装指令和命令,就能让用户在本地快速运行开源大型语言模型。此外,Ollama 还提供了类似 OpenAI 的 API 接口和聊天界面,方便用户使用不同模型,并且具备模型库管理系统1。
通过Ollama的源代码我们发现,其实创建运行大模型,Ollama使用Go语言CGO调用了llama.cpp的C++库,从而实现运行大模型.
可以看到代码CGO的影子.
所以底层运行的机制是靠llama.cpp作为底层运行大模型的支撑.
6、Docker的理念加持
Ollama参考了Docker的理念,将大模型文件和所需配置信息等也进行了封装为镜像的概念,镜像便于分发,同时降低了开发者运行的门槛,只需要拉取对应大模型镜像,使用ollama run一键就能启动大模型服务。
Ollama的镜像文件本质就是一个特殊的压缩包,压缩包里包含了GGUF大模型文件、一些配置参数文件. 构建自己的Ollama镜像使用Modelfile的方式进行构建,整个语法有点参照Dockerfile.以下是构建一个自定义Model镜像的Modelfile:
# 基础模型
FROM deepseek:1.5b
# 自定义模型的名称和描述
NAME my_custom_deepseek
DESCRIPTION "A custom model based on deepseek:1.5b with custom data"
# 自定义数据的路径,这里假设自定义数据文件在当前目录下
PARAMETER file "./custom_data.txt"
# 可以根据需要调整的其他参数
PARAMETER num_train_epochs 3
PARAMETER learning_rate 2e-5
PARAMETER per_device_train_batch_size 4
FROM
指令:指定基础模型,这里使用deepseek:1.5b
作为基础,后续的微调操作将基于这个模型进行。NAME
指令:为自定义模型指定一个名称,这里命名为my_custom_deepseek
,方便后续引用和管理。DESCRIPTION
指令:对自定义模型进行简要描述,说明该模型是基于deepseek:1.5b
并加入了自定义数据。PARAMETER
指令:file
:指定自定义数据文件的路径,你需要将实际的自定义数据文件路径替换为./custom_data.txt
。num_train_epochs
:指定训练的轮数,这里设置为 3 轮,你可以根据实际情况调整。learning_rate
:学习率,控制模型在训练过程中参数更新的步长,这里设置为2e-5
,也是一个常见的取值,可根据效果调整。per_device_train_batch_size
:每个设备(如 GPU)上的训练批次大小,这里设置为 4,你可以根据设备的内存情况进行调整
构建build Model镜像命令:
ollama create my_custom_deepseek -f Modelfile
运行镜像:
ollama run my_custom_deepseek
Ollama只是参考借鉴了Docker的思想,但是底层并没有关于容器的相关使用。
7、透过现象看本质
1、Ollama的本质就是,使用Go作为编程语言,构建HTTP服务提供API接口对内部的Ollama镜像、Ollama运行"大模型容器"进行管理, 内部使用CGO调用llama.cpp的能力来运行大模型. 降低了我们从零开始部署大模型的门槛。 底层运行还是依赖llama.cpp,只是应用层使用Go包了一层,让我们更方便、快捷的管理和运行大模型.
2、Ollama上面提供的镜像,要么是大模型的维护者,要么是一些开发者、官方维护者,首先去对应官网渠道、Hugging Face获取GGUF文件或者其他大模型格式文件, 通过编写Modelfile的构建镜像,最后在Ollama进行发布。 用户拉取镜像进行运行即可。
三、总结
知其然也要知其所以然, Ollama第一次使用我就很疑惑是不是底层套了一层docker容器化技术,然后再结合大模型做的包装。 后来经过分析,确实和容器没太大关系,就是思想做了一些借鉴。
并且从分析过程中知道了,GGUF大模型文件的运行依靠的是llama.cpp底层进行支撑运行,那就意味着性能其实不差,毕竟是c++底层来支撑的,之前以为是使用python sdk之类的来运行的。