LLM Exploration: Offline Deployment of Ollama and one-api Services
Offline deploy Ollama? Manually download and upload, import model files—ugh, what a hassle. Using Docker for one-api, tiktoken needs downloading and renaming, even more tedious. Adding channels? Simple.
目录11 个章节
Preface
Previously, I deployed DeepSeek using Ollama on a Linux server.
This time, I'm deploying on a server without public internet (or rather, one with significant restrictions), and I've encountered some pitfalls. Documenting them here.
ollama
ollama naturally cannot use the online installation script.
According to the ollama documentation, first download the installation package on your local computer based on the server's operating system and CPU architecture.
curl -L https://ollama.com/download/ollama-linux-amd64.tgz -o ollama-linux-amd64.tgz
Then use tools like scp to upload it to the server.
scp ollama-linux-amd64.tgz server-address:/temp
After connecting to the server, extract and install by following the ollama documentation (see the first reference).
sudo tar -C /usr -xzf ollama-linux-amd64.tgz
At this point, you can already run the ollama program.
ollama serve
Then add it as a service, which is also the officially recommended approach by ollama for easier management.
sudo useradd -r -s /bin/false -U -m -d /usr/share/ollama ollama
sudo usermod -a -G ollama $(whoami)
Create a new ollama.service file under /etc/systemd/system.
[Unit]
Description=Ollama Service
After=network-online.target
[Service]
ExecStart=/usr/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=3
Environment="PATH=$PATH"
[Install]
WantedBy=default.target
Then enable the service.
sudo systemctl daemon-reload
sudo systemctl enable ollama
At this point, the installation of ollama is complete.
Model Deployment
An offline server cannot use ollama pull to fetch models.
You need to first download the model on your local machine, where you can run the ollama pull command.
Then, locate the model files and upload them to the server.
The general idea is like this, and the specifics will be introduced next.
Finding Local Model Files
By default, if there is no special configuration, ollama's model files are all located in ~/.ollama/models/blobs.
First, execute the command to see the path of a specified model. For example, to find the deepseek-r1:32b model:
ollama show deepseek-r1:32b --modelfile
Output after executing the command (excerpt):
FROM C:\Users\deali\.ollama\models\blobs\sha256-96c415656d377afbff962f6cdb2394ab092ccbcbaab4b82525bc4ca800fe8a49
TEMPLATE """{{- if .System }}{{ .System }}{{ end }}
{{- range $i, $_ := .Messages }}
{{- $last := eq (len (slice $.Messages $i)) 1}}
{{- if eq .Role "user" }}<|User|>{{ .Content }}
{{- else if eq .Role "assistant" }}<|Assistant|>{{ .Content }}{{- if not $last }}<|end▁of▁sentence|>{{- end }}
{{- end }}
{{- if and $last (ne .Role "assistant") }}<|Assistant|>{{- end }}
{{- end }}"""
PARAMETER stop <|begin▁of▁sentence|>
PARAMETER stop <|end▁of▁sentence|>
PARAMETER stop <|User|>
PARAMETER stop <|Assistant|>
You can see this line:
FROM C:\Users\deali\.ollama\models\blobs\sha256-96c415656d377afbff962f6cdb2394ab092ccbcbaab4b82525bc4ca800fe8a49
This is the local path where ollama downloaded the model.
Upload this file to the server.
Exporting the Modelfile
This file format is similar to a Dockerfile.
Use the following command to export it:
ollama show deepseek-r1:32b --modelfile > Modelfile
Then, this file should also be uploaded to the server.
Importing a Model on the Server
After uploading the model files and Modelfile, place them in the same directory.
First, rename the file for easier subsequent import.
mv sha256-96c415656d377afbff962f6cdb2394ab092ccbcbaab4b82525bc4ca800fe8a49 deepseek-r1_32b.gguf
Next, edit the Modelfile. Change the FROM line to match the renamed model file name.
FROM ./deepseek-r1_32b.gguf
Then, run the following command to import.
ollama create deepseek-r1:32b -f Modelfile
If everything goes as expected, the import will be successful. You can run ollama list to verify whether the model has been imported.
one-api
One API is an open-source LLM (Large Language Model) API management and distribution system. It aims to provide unified access to various large models through a standard OpenAI API format, working out of the box. It supports multiple mainstream large models, including the OpenAI ChatGPT series, Anthropic Claude series, Google PaLM2/Gemini series, Mistral series, ByteDance Doubao (豆包) large model, Baidu Wenxin Yiyan (文心一言) series models, Alibaba Tongyi Qianwen (通义千问) series models, iFlytek Spark (讯飞星火) cognitive large model, Zhipu ChatGLM series models, Tencent Hunyuan (混元) large model, and more.
Docker Deployment
one-api is built using Go's Gin framework, making it easy to deploy. I typically use Docker for deployment, so I won't elaborate on that part here.
services:
db:
image: mysql:8.1.0
container_name: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: mysql-password
volumes:
- ./data:/var/lib/mysql
one-api:
image: justsong/one-api
container_name: one-api
restart: always
ports:
- "3000:3000"
depends:
- db
environment:
- SQL_DSN=root:mysql-password@tcp(db:3306)/one_api
- TZ=Asia/Shanghai
- TIKTOKEN_CACHE_DIR=/TIKTOKEN_CACHE_DIR
volumes:
- ./data:/data
- ./TIKTOKEN_CACHE_DIR:/TIKTOKEN_CACHE_DIR
networks:
default:
name: one-api
Solving tiktoken Issues
The problem encountered is that it depends on the tiktoken library, which requires internet access to download token encoders.
The solution involves checking the error logs, for example:
one-api | [FATAL] 2025/02/17 - 10:47:21 | relay/adaptor/openai/token.go:26 [InitTokenEncoders] failed to get gpt-3.5-turbo token encoder: Get "https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken": dial tcp 57.150.97.129:443: i/o timeout, if you are using in offline environment, please set TIKTOKEN_CACHE_DIR to use exsited files
This requires downloading from https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken.
First, download the file locally and then upload it to the server.
But this alone is not sufficient.
tiktoken only recognizes URLs by their SHA-1 hash.
Generate the SHA-1:
TIKTOKEN_URL=https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken
echo -n $TIKTOKEN_URL | sha1sum | head -c 40
You can also combine it into a single command:
echo -n "https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken" | sha1sum | head -c 40
In this command, echo -n is used to output the specified URL string (the -n parameter's function is to prevent appending a newline character at the end of the output), sha1sum calculates its SHA-1 hash value, and head -c 40 extracts the first 40 characters, which are the first 40 bits of the hash value.
The execution result is:
9b5ad71b2ce5302211f9c61530b329a4922fc6a4
Then rename the cl100k_base.tiktoken file to the output 9b5ad71b2ce5302211f9c61530b329a4922fc6a4.
In the docker-compose.yaml mentioned earlier, we have already specified the TIKTOKEN_CACHE_DIR environment variable.
Then place this 9b5ad71b2ce5302211f9c61530b329a4922fc6a4 file in the TIKTOKEN_CACHE_DIR directory.
If you encounter similar errors later, repeat the above steps until there are no more errors.
The version I currently use has only downloaded two encoders.
Adding Ollama Channel in OneApi
This can be a bit tricky due to Docker networking issues.
There are several approaches. One is to run the OneApi container in host network mode.
Another is to use the host.docker.internal address.
In both cases, the prerequisite is that Ollama's host is set to 0.0.0.0. For configuration details, you can refer to my previous article: LLM Exploration: Local Deployment of the DeepSeek-R1 Model.
When adding the channel, select Ollama as the type.
In the custom model section, enter the model we deployed: deepseek-r1:32b.
Then, set the proxy to http://host.docker.internal:11434.
Note: In a Linux environment, host.docker.internal may not work. However, you can directly use the host machine's IP address. For example, if the host machine's IP address is 192.168.1.100, you can use http://192.168.1.100:11434 in OneApi to access the Ollama service.
References
_EOF_
LLM Exploration: Offline Deployment of Ollama and one-api Services
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
LLM探索:大模型背后的向量魔法,Embedding技术初探
Embedding技术从Word Embedding发展到动态预训练模型,无处不在,但本文只是过时的基础。LLM时代,向量魔法如此关键,作者却拖更太久,内容早该更新了。
2026-05-09 · LLM · 约 1 分钟
2GB 显存还能跑大模型吗?我在 MX250 老笔记本上部署 Qwen3.5 2BB
七年前的Matebook14,MX250显存2GB,硬塞Qwen3.5 2B——这届玩家是真的敢。核心思路倒是比模型选择更值得学:先看清楚硬件预算,再决定能跑什么,而不是硬上7B然后等CPU掉帧到怀疑人生。1.81GiB直接顶满2GB显存,KV Cache挤出来的空间里,4K Context刚好够用。至于Agent场景?省省吧,2B让MX250当推理节点做轻量任务已经仁至义尽。
2026-09-15 · LLM · 约 1 分钟
LLM探索:DeepSeek火爆全网,官网宕机?本地部署一个随便玩
DeepSeek官网又崩?本地部署14b模型,web界面倒还凑合。国产大模型热度高,服务器不行就自己搭,呵。代码能力待验证,反正比官网强。
2026-05-09 · LLM · 约 1 分钟
ChatGLM-6B本地部署
下载项目代码 git clone https://github.com/THUDM/ChatGLM-6B.git 创建虚拟环境,建议使用 conda 管理 conda create -n chatglm python==3.8 安装依赖 conda activate chatglm pip install -r requirements.txt conda install cudatoolkit=
2026-05-09 · LLM · 约 1 分钟
讨论
共 0 条加载评论中…