Ollama 模型迁移备份工具 ollamab
背景
ollama 模型和相关配置文件默认都放在 models 文件夹下,想要把指定模型迁移到其他电脑比较麻烦,所以就有了该工具。还有就是模型下载本身就慢,一次下载多台使用减少下载次数。最重要的是公司电脑下载快,家里下载慢,在公司下载拷贝回家用
如何使用
下载地址:
- Window ollamab.exe
- Linux ollamab
命令
ollamab 模型名称+型号(和 ollama 名称列表一致) 输出路径 (可选)
ollamab.exe qwen:0.5b D:/
执行结果
D:\code\private\model-backup>ollamab.exe qwen:0.5b
模型路径: D:\ai\.ollama\models
开始打包,耐心等待…………
添加到 ZIP 中: blobs\sha256-fad2a06e4cc705c2fa8bec5477ddb00dc0c859ac184c34dcc5586663774161ca
添加到 ZIP 中: blobs\sha256-41c2cf8c272f6fb0080a97cd9d9bd7d4604072b80a0b10e7d65ca26ef5000c0c
添加到 ZIP 中: blobs\sha256-1da0581fd4ce92dcf5a66b1da737cf215d8dcf25aa1b98b44443aaf7173155f5
添加到 ZIP 中: blobs\sha256-f02dd72bb2423204352eabc5637b44d79d17f109fdb510a7c51455892aa2d216
添加到 ZIP 中: manifests\registry.ollama.ai\library\qwen\0.5b
zip文件创建成功: qwen-0.5b.zip
目标电脑
将打包的 zip 拷贝到目标电脑 models 下直接解压到当前目录即可
ollama
ollama list 输出所有模型命令
NAME ID SIZE MODIFIED
gemma2:9b ff02c3702f32 5.4 GB 5 hours ago
phi:2.7b e2fd6321a5fe 1.6 GB 5 hours ago
qwen:7b 2091ee8c8d8f 4.5 GB 4 days ago
qwen:0.5b b5dc5e784f2a 394 MB 4 days ago
llama3.1:8b 46e0c10c039e 4.9 GB 5 days ago
deepseek-r1:1.5b a42b25d8c10a 1.1 GB 6 days ago
deepseek-r1:7b 0a8c26691023 4.7 GB 8 days ago
Ollama 在 Windows 上存储文件在几个不同的位置。您可以通过以下步骤查看它们:
按
<cmd>+R键并输入:explorer %LOCALAPPDATA%\Ollama:包含日志和下载的更新- app.log:最近的 GUI 应用程序日志
- server.log:最近的服务器日志
- upgrade.log:升级日志输出
explorer %LOCALAPPDATA%\Programs\Ollama:包含二进制文件(安装器将其添加到用户 PATH 中)explorer %HOMEPATH%\.ollama:包含模型和配置explorer %TEMP%:包含临时执行文件,在一个或多个ollama*目录中
源码
/**
* @Time : 2025/2/14
* @File : main.go
* @Software: ollamab
* @Author : Mr.Fang
* @Description: 备份 ollama 模型
*/
package main
import (
"archive/zip"
"encoding/json"
"fmt"
"io"
"log"
"os"
"path/filepath"
"runtime"
"strings"
)
var modelPath = ""
// 初始化获取模型文件路径,优先从系统环境变量获取,其次获取默认路径
func init() {
models := os.Getenv("OLLAMA_MODELS")
if len(models) > 0 {
modelPath = models
} else {
// Window
if runtime.GOOS == "windows" {
home, err := os.UserHomeDir()
if err != nil {
log.Panicln("获取用户主目录失败:", err)
}
modelPath = filepath.Join(home, ".ollama", "models")
} else { // Linux
modelPath = filepath.Join("/usr/share/ollama/", ".ollama", "models")
}
}
fmt.Println("模型路径:", modelPath)
}
// 将文件或文件夹添加到 zip 中
func addToZip(zipWriter *zip.Writer, filePath, baseFolder string) error {
// 计算文件的相对路径
relativePath, err := filepath.Rel(baseFolder, filePath)
if err != nil {
return err
}
fmt.Println("添加到 ZIP 中:", relativePath)
// 如果是目录,则创建空目录
info, err := os.Stat(filePath)
if err != nil {
return err
}
// 如果是目录,创建空目录
if info.IsDir() {
_, err := zipWriter.Create(relativePath + "/")
return err
}
// 如果是文件,创建文件条目
fileInZip, err := zipWriter.Create(relativePath)
if err != nil {
return err
}
// 打开文件并复制内容到zip中
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
// 复制文件内容到zip
_, err = io.Copy(fileInZip, file)
return err
}
// 模型相关所有文件路径
func blobsPath(modelDataPath, basePath string) []string {
file, err := os.ReadFile(modelDataPath)
if err != nil {
fmt.Println("model data 文件读取错误!", err)
}
// 转 map
var modelData map[string]interface{}
var blobsPath []string
err = json.Unmarshal(file, &modelData)
if err != nil {
fmt.Println("model data 转换错误!", err)
}
// 层数据
layers := modelData["layers"].([]interface{})
// 模型详情信息
layers = append(layers, modelData["config"].(interface{}))
for _, layer := range layers {
item := layer.(map[string]interface{})
digest := item["digest"].(string) // sha256
digest = strings.ReplaceAll(digest, ":", "-")
join := filepath.Join(basePath, "blobs", digest)
// 使用 os.Stat 检查文件是否存在
fileInfo, _ := os.Stat(join)
if fileInfo != nil {
blobsPath = append(blobsPath, join)
}
}
return blobsPath
}
// build 打包 zip
func build(name string, output string, folderPaths []string) {
fmt.Println("开始打包,耐心等待…………")
// 创建目标zip文件
zipFilePath := filepath.Join(output, name)
zipFile, err := os.Create(zipFilePath)
if err != nil {
fmt.Println("创建zip文件失败:", err)
return
}
defer zipFile.Close()
// 创建zip写入器
zipWriter := zip.NewWriter(zipFile)
defer zipWriter.Close()
// 逐个添加文件或目录到zip文件中
for _, filePath := range folderPaths {
// 注意:baseFolder 是我们希望在zip文件中根目录
err := addToZip(zipWriter, filePath, modelPath)
if err != nil {
fmt.Println("添加文件到zip失败:", err)
return
}
}
fmt.Println("zip文件创建成功:", zipFilePath)
}
func main() {
args := os.Args[1:]
if len(args) == 0 {
fmt.Println("参数: ollamab 名称:型号(必填) 指定输出路径,默认输出当前路径(可选)")
fmt.Println("示例: ollamab deepseek-r1:1.5b ")
fmt.Println("示例: ollamab deepseek-r1:1.5b D:/models")
fmt.Println("示例: ollamab lrs33/bce-embedding-base_v1:latest")
return
}
arg := strings.Split(args[0], ":")
name := arg[0]
version := arg[1]
output := "./"
if len(args) == 2 {
output = args[1]
}
// 配置文件路径
library := filepath.Join(modelPath, "manifests", "registry.ollama.ai", "library", name, version)
// 特殊情况,用户自己分享的模型
contains := strings.Contains(name, "/")
if contains {
libs := strings.Split(name, "/")
library = filepath.Join(modelPath, "manifests", "registry.ollama.ai", libs[0], libs[1], version)
// 替换 "/" 否则无法创建 zip
name = strings.ReplaceAll(name, "/", "-")
}
folderPaths := blobsPath(library, modelPath)
// 模型路径
folderPaths = append(folderPaths, library)
// 打包
build(fmt.Sprintf("%s-%s.zip", name, version), output, folderPaths)
}
更新说明
- 解决用户自己分享的模型备份路径问题
- 模型
config配置文件未拷贝导致ollama list未显示迁移模型,需要执行ollama run 模型 - Linux 下默认模型路径未处理
Ollama 模型迁移备份工具 ollamab的更多相关文章
- 规划将 IaaS 资源从经典部署模型迁移到 Azure Resource Manager
尽管 Azure 资源管理器提供了许多精彩功能,但请务必计划迁移,以确保一切顺利进行. 花时间进行规划可确保执行迁移活动时不会遇到问题. Note 以下指导的主要参与者为 Azure 客户顾问团队,以 ...
- 有关从经典部署模型迁移到 Azure Resource Manager 部署模型的常见问题
此迁移计划是否影响 Azure 虚拟机上运行的任何现有服务或应用程序? 不可以. VM(经典)是公开上市的完全受支持的服务. 你可以继续使用这些资源来拓展你在 Azure 上的足迹. 如果我近期不打算 ...
- 使用 Azure PowerShell 将 IaaS 资源从经典部署模型迁移到 Azure Resource Manager
以下步骤演示了如何使用 Azure PowerShell 命令将基础结构即服务 (IaaS) 资源从经典部署模型迁移到 Azure Resource Manager 部署模型. 也可根据需要通过 Az ...
- 使用 Azure CLI 将 IaaS 资源从经典部署模型迁移到 Azure Resource Manager 部署模型
以下步骤演示如何使用 Azure 命令行接口 (CLI) 命令将基础结构即服务 (IaaS) 资源从经典部署模型迁移到 Azure Resource Manager 部署模型. 本文中的操作需要 Az ...
- MySQL 数据库备份种类以及常用备份工具汇总
1,数据库备份种类 按照数据库大小备份,有四种类型,分别应用于不同场合,下面简要介绍一下: 1.1完全备份 这是大多数人常用的方式,它可以备份整个数据库,包含用户表.系统表.索引.视图和存储过程等所有 ...
- Mysql备份工具mysqldump和mysqlhotcopy
(1).Mysql备份类型 1)按照备份时对数据库的影响分为 Hot backup(热备):也叫在线备份.指在数据库运行中直接备份,对正在运行的数据库没有任何影响. Cold backup(冷备):也 ...
- [转帖]服务器备份工具:Amanda,Bakula,Clonezilla,Rsnapshot,Mondo Rescue
服务器备份工具:Amanda,Bakula,Clonezilla,Rsnapshot,Mondo Rescue https://ywnz.com/linuxyffq/5270.html 改天试用一下. ...
- MySQL数据备份之逻辑备份工具mysqldump
#前言:我们知道对数据进行备份很重要,出现非正常操作可以进行对数据进行恢复,下面我们就来使用一下mysql数据库自带的一个逻辑备份工具mysqldump 1.简单概述 #mysqldump:mysql ...
- SQLSERVER自动定时(手动)备份工具
最近项目需要,写了一个小工具软件: 1.实时显示监控 2.可多选择备份数据库 3.按每天定时备份 4.备份文件自动压缩 5.删除之前备份文件 直接上图 1.备份监控界面: 2.数据库设置: 附工具下载 ...
- MySQL 5.7 mysqlpump 备份工具说明
背景: MySQL5.7之后多了一个备份工具:mysqlpump.它是mysqldump的一个衍生,mysqldump就不多说明了,现在看看mysqlpump到底有了哪些提升,可以查看官方文档,这里针 ...
随机推荐
- C#/.NET/.NET Core优秀项目和框架2024年11月简报
前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的详细介绍.功能特点.使用方式以及部分功能 ...
- IEDA 控制台乱码解决
1.修改idea 目录下的文件 idea64.exe.vmoptions idea.exe.vmoptions 在这个文件尾部增加 -Dfile.encoding=UTF-8 2.编辑ieda 文件配 ...
- Java框架 —— Spring
Spring 简介 一般来说,Spring指的是SpringFramework,它提供了很多功能,例如:控制反转(IOC).依赖注入 (DI).切面编程(AOP).事务管理(TX) 主要 jar ...
- echarts 图表设置默认选中
echarts:https://echarts.apache.org/zh/api.html#events.legendselected tfjy1997:https://blog.csdn.net/ ...
- [.NET Blog] .NET Aspire 测试入门
https://devblogs.microsoft.com/dotnet/getting-started-with-testing-and-dotnet-aspire/ 自动化测试是软件开发的重要一 ...
- T语言开发笔记1
为什么会有开发语言的想法 在2012年,我准备开发一个给前端切图使用的屏幕取色器. 需求很简单,前端经常需要获取设计稿特定位置的颜色代码.虽然当时 PhotoShop 提供了内部取色器,但操作麻烦,而 ...
- 【人工智能】【Python】Anacond基础操作
# 001.在 Anaconda 中使用 Conda 管理 Python 环境 工具:Anaconda Prompt(Anaconda)| 请使用管理员权限运行 更新Anaconda conda up ...
- Qt音视频开发41-文件推流(支持网页和播放器播放并切换进度)
一.前言 本功能最初也是有一些人提过类似的需求,就是能不能将本地的音视频文件,通过纯Qt程序推流出去,然后用户可以直接在网页上播放,也可以用各种播放器播放,然后还可以任意切换播放进度,其实说白了就是个 ...
- Intellij IDEA部署Web项目到tomcat时提示:Error:Cannot build Artifact ':war exploded' because it is included into a circul
在Idea中使用Maven创建父子工程,第一个Model的那个项目可以很好的运行,在创建一个Model运行时报这个错.原因是tomcat部署了多个Web项目,可能最开始是两个项目的配置文件混用用,最后 ...
- Web网页端IM产品RainbowChat-Web的v7.2版已发布
一.关于RainbowChat-Web RainbowChat-Web是一套Web网页端IM系统,是RainbowChat的姊妹系统(RainbowChat是一套基于开源IM聊天框架 MobileIM ...