Location>code7788 >text

Ollama Model Migration Backup Tool ollamab

Popularity:165 ℃/2025-02-18 09:46:05

background

ollamaThe model and related configuration files are placed by defaultmodelsIn the folder, it is more troublesome to migrate the specified model to other computers, so I have this tool. Also, the model download itself is slow, and multiple units are used to reduce the number of downloads. The most important thing is that the company's computer downloads are fast and the home downloads are slow. Download and copy them in the company and use them home. 😄

How to use

Download address

  • Window
  • Linux ollamab

Order

ollamab Model name + model(Consistent with the ollama name list)Output path(Optional)

 qwen:0.5b D:/

Execution results

D:\code\private\model-backup> qwen:0.5b
 Model path: D:\ai\.ollama\models
 Start packing, wait patiently……
 Add to ZIP: blobs\sha256-fad2a06e4cc705c2fa8bec5477ddb00dc0c859ac184c34dcc5586663774161ca
 Add to ZIP: blobs\sha256-41c2cf8c272f6fb0080a97cd9d9bd7d4604072b80a0b10e7d65ca26ef5000c0c
 Add to ZIP: blobs\sha256-1da0581fd4ce92dcf5a66b1da737cf215d8dcf25aa1b98b44443aaf7173155f5
 Add to ZIP: blobs\sha256-f02dd72bb2423204352eabc5637b44d79d17f109fdb510a7c51455892aa2d216
 Add to ZIP: manifests\\library\qwen\0.5b
 The zip file was created successfully: qwen-0.

Target computer

Will be packagedzipCopy to the target computermodelsJust unzip it to the current directory

ollama

ollama listOutput all model commands

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 stores files on Windows in several different locations. You can view them in the following steps:

  • according to<cmd>+RKey and enter:

    • explorer %LOCALAPPDATA%\Ollama: Updates containing logs and downloads

      • : Recent GUI application logs
      • : Recent server logs
      • : Upgrade log output
    • explorer %LOCALAPPDATA%\Programs\Ollama: Contains the binary file (the installer adds it to the user PATH)

    • explorer %HOMEPATH%\.ollama: Contains model and configuration

    • explorer %TEMP%: Contains temporary execution files in one or moreollama*In the directory

Source code

/**
  * @Time: 2025/2/14
  * @File:
  * @Software: ollamab
  * @Author:
  * @Description: Backup ollama model
  */

 package main

 import (
 "archive/zip"
 "encoding/json"
 "fmt"
 "io"
 "log"
 "os"
 "path/filepath"
 "runtime"
 "strings"
 )

 var modelPath = ""

 // Initialize the path to get the model file, priority is obtained from the system environment variables, and secondly get the default path
 func init() {
 models := ("OLLAMA_MODELS")
 if len(models) > 0 {
 modelPath = models
 } else {
 // Window
 if == "windows" {
 home, err := ()
 if err != nil {
 ("Failed to obtain the user home directory:", err)
 }
 modelPath = (home, ".ollama", "models")
 } else { // Linux
 modelPath = ("/usr/share/ollama/", ".ollama", "models")
 }
 }
 ("Model Path:", modelPath)
 }

 // Add a file or folder to the zip
 func addToZip(zipWriter *, filePath, baseFolder string) error {
 // Calculate the relative path of the file
 relativePath, err := (baseFolder, filePath)
 if err != nil {
 return err
 }

 ("Add to ZIP:", relativePath)

 // If it is a directory, create an empty directory
 info, err := (filePath)
 if err != nil {
 return err
 }

 // If it is a directory, create an empty directory
 if () {
 _, err := (relativePath + "/")
 return err
 }

 // If it is a file, create a file entry
 fileInZip, err := (relativePath)
 if err != nil {
 return err
 }

 // Open the file and copy the content into the zip
 file, err := (filePath)
 if err != nil {
 return err
 }
 defer ()

 // Copy the file contents to zip
 _, err = (fileInZip, file)
 return err
 }

 // All file paths related to the model
 func blobsPath(modelDataPath, basePath string) []string {
 file, err := (modelDataPath)
 if err != nil {
 ("Model data file read error!", err)
 }
 // Turn to map
 var modelData map[string]interface{}
 var blobsPath []string
 err = (file, &modelData)
 if err != nil {
 ("model data conversion error!", err)
 }
 // Layer data
 layers := modelData["layers"].([]interface{})
 // Model details
 layers = append(layers, modelData["config"].(interface{}))

 for _, layer := range layers {
 item := layer.(map[string]interface{})
 digest := item["digest"].(string) // sha256
 digest = (digest, ":", "-")
 join := (basePath, "blobs", digest)
 // Use to check if the file exists
 fileInfo, _ := (join)
 if fileInfo != nil {
 blobsPath = append(blobsPath, join)
 }
 }
 return blobsPath
 }

 // build package zip
 func build(name string, output string, folderPaths []string) {
 ("Start packing, wait patiently…...")
 // Create the target zip file
 zipFilePath := (output, name)
 zipFile, err := (zipFilePath)
 if err != nil {
 ("Create a zip file failed:", err)
 Return
 }
 defer ()

 // Create a zip writer
 zipWriter := (zipFile)
 defer ()

 // Add files or directories to zip files one by one
 for _, filePath := range folderPaths {
 // Note: baseFolder is the root directory we want to use in the zip file
 err := addToZip(zipWriter, filePath, modelPath)
 if err != nil {
 ("Add file to zip failed:", err)
 Return
 }
 }
 ("zip file creation successfully:", zipFilePath)
 }

 func main() {
 args := [1:]

 if len(args) == 0 {
 ("Parameter: ollamab Name: Model (required) Specify the output path, default output current path (optional)")
 ("Example: ollamab deepseek-r1:1.5b")
 ("Example: ollamab deepseek-r1:1.5b D:/models")
 ("Example: ollamab lrs33/bce-embedding-base_v1:latest")
 Return
 }
 arg := (args[0], ":")
 name := arg[0]
 version := arg[1]
 output := "./"
 if len(args) == 2 {
 output = args[1]
 }
 // Configuration file path
 library := (modelPath, "manifests", "", "library", name, version)
 // Special circumstances, the model shared by the user themselves
 contains := (name, "/")
 if contains {
 libs := (name, "/")
 library = (modelPath, "manifests", "", libs[0], libs[1], version)
 // Replace "/" Otherwise, zip cannot be created
 name = (name, "/", "-")
 }
 folderPaths := blobsPath(library, modelPath)
 // Model path
 folderPaths = append(folderPaths, library)
 	// Pack
 build(("%s-%", name, version), output, folderPaths)

 }

Update instructions

  • Solve the problem of model backup path shared by users themselves
  • ModelconfigThe configuration file is not copied, resulting inollama listMigration model is not shown, need to be executedollama run model
  • The default model path under Linux is not processed