使用Ollama实现模型一键备份与恢复(附Windows/Linux脚本)

前言

在使用Ollama进行大模型开发时,模型备份与迁移是开发者常遇到的需求。本文将介绍无需下载重复下载模型的备份恢复方案,并提供Windows/Linux双平台自动化脚本实现一键操作。

一、备份恢复原理

备份核心要素

  1. Modelfile:模型定义文件(包含模型架构信息)

  2. Blob文件:模型权重二进制文件(存储在Ollama仓库中)

工作流程
 

[备份] Modelfile导出 + Blob文件拷贝 → 备份目录
[恢复] Modelfile修改路径 + 创建新模型 → 恢复运行环境

二、手动操作步骤(理解原理)
2.1 单模型备份

# 导出Modelfile(示例模型名:llama3.2:1b)
ollama show llama3.2:1b --modelfile > modelfile

# 定位并复制Blob文件(关键步骤!)
# Windows默认路径:
C:\Users\<用户名>\.ollama\models\blobs\sha256-xxx
# Linux默认路径:
~/.ollama/models/blobs/sha256-xxx

2.2 模型恢复
 

# 修改Modelfile的FROM路径为备份的blob绝对路径
FROM /backup_path/sha256-74701a8c35f6c8d9a4b91f3f3497643001d63e0c7a84e085bed452548fa88d45

# 创建新模型
ollama create your_model_name -f ./modelfile

三、自动化脚本使用说明
3.1 Windows脚本(ollama_model_transfer.bat)
 

@echo off
setlocal enabledelayedexpansion

:: 设置标题和颜色
title Ollama模型导入导出工具
color 0A

:: 设置UTF-8编码,减少乱码问题
chcp 65001 > nul

:: 默认路径设置
set "DEFAULT_EXPORT_PATH=%USERPROFILE%\Desktop\ollama_backup"
set "DEFAULT_IMPORT_PATH=%USERPROFILE%\Desktop\ollama_backup"
set "OLLAMA_MODELS_PATH=%USERPROFILE%\.ollama\models"

:MAIN_MENU
cls
echo ====================================
echo      Ollama模型导入导出工具
echo ====================================
echo.
echo 请选择操作:
echo [1] 导出/备份模型
echo [2] 导入模型
echo [3] 退出
echo.
set /p CHOICE="请输入选项 (1-3): "

if "%CHOICE%"=="1" goto EXPORT_MENU
if "%CHOICE%"=="2" goto IMPORT_MENU
if "%CHOICE%"=="3" goto EXIT_SCRIPT
goto MAIN_MENU

:EXPORT_MENU
cls
echo ====================================
echo         导出/备份Ollama模型
echo ====================================
echo.

:: 设置导出路径
set "EXPORT_PATH=%DEFAULT_EXPORT_PATH%"
set /p CUSTOM_PATH="请输入导出路径 [默认: %EXPORT_PATH%]: "
if not "%CUSTOM_PATH%"=="" set "EXPORT_PATH=%CUSTOM_PATH%"

:: 检查和创建导出目录
if not exist "%EXPORT_PATH%" (
    echo 创建目录: %EXPORT_PATH%
    mkdir "%EXPORT_PATH%"
)

:: 设置UTF-8代码页
chcp 65001 > nul
echo 已设置UTF-8编码,减少乱码问题

:: 列出可用模型
echo.
echo 可用的Ollama模型:
echo -------------------
set MODEL_COUNT=0
for /f "tokens=*" %%a in ('ollama list') do (
    set "LINE=%%a"
    if not "!LINE:~0,4!"=="NAME" (
        if not "!LINE!"=="" (
            set /a MODEL_COUNT+=1
            set "MODEL_!MODEL_COUNT!=!LINE!"
            echo !MODEL_COUNT!. !LINE!
        )
    )
)

if %MODEL_COUNT% EQU 0 (
    echo 没有找到可用的模型。
    pause
    goto MAIN_MENU
)

:: 选择模型
echo.
set /p MODEL_SELECT="请选择要导出的模型 (1-%MODEL_COUNT%): "

:: 验证输入
if %MODEL_SELECT% LSS 1 goto EXPORT_MENU
if %MODEL_SELECT% GTR %MODEL_COUNT% goto EXPORT_MENU

:: 获取模型名称和格式化文件名
set "SELECTED_MODEL_LINE=!MODEL_%MODEL_SELECT%!"
for /f "tokens=1" %%a in ("!SELECTED_MODEL_LINE!") do set "ORIGINAL_MODEL_NAME=%%a"

:: 从模型行提取模型名称和标签
for /f "tokens=1,2 delims=:" %%a in ("!ORIGINAL_MODEL_NAME!") do (
    set "MODEL_NAME=%%a"
    set "MODEL_TAG=%%b"
)

:: 为文件名创建安全的名称(替换所有冒号为下划线)
set "SAFE_MODEL_NAME=!ORIGINAL_MODEL_NAME!"
set "SAFE_MODEL_NAME=!SAFE_MODEL_NAME::=_!"
set "MODEL_FOLDER=%EXPORT_PATH%\!SAFE_MODEL_NAME!"

:: 创建模型专用文件夹
echo 创建模型文件夹: !MODEL_FOLDER!
mkdir "!MODEL_FOLDER!" 2>nul

:: 生成Modelfile - 使用PowerShell确保UTF-8编码
echo 正在导出Modelfile...
powershell -Command "& { ollama show !ORIGINAL_MODEL_NAME! --modelfile | Out-File -FilePath '!MODEL_FOLDER!\modelfile' -Encoding utf8 }"
if not exist "!MODEL_FOLDER!\modelfile" (
    echo 使用PowerShell导出失败,尝试直接导出...
    ollama show !ORIGINAL_MODEL_NAME! --modelfile > "!MODEL_FOLDER!\modelfile"
    if not exist "!MODEL_FOLDER!\modelfile" (
        echo 错误: 无法导出Modelfile!
        pause
        goto MAIN_MENU
    )
)

:: 从Modelfile中提取SHA值 - 特别注意只查找以FROM开头的行
echo 正在查找模型文件路径...
set "FROM_LINE="
for /f "tokens=*" %%a in ('type "!MODEL_FOLDER!\modelfile"') do (
    set "LINE=%%a"
    if "!LINE:~0,4!"=="FROM" (
        set "FROM_LINE=!LINE:~5!"
        echo 找到FROM行: FROM !FROM_LINE!
    )
)

if "!FROM_LINE!"=="" (
    echo 警告: 在Modelfile中未找到FROM行
    echo 正在尝试使用findstr查找...
    for /f "tokens=1,*" %%a in ('findstr /b "FROM " "!MODEL_FOLDER!\modelfile"') do (
        set "FROM_LINE=%%b"
        echo 使用findstr找到: FROM !FROM_LINE!
    )
)

echo 提取的模型文件路径: !FROM_LINE!

:: 尝试从绝对路径中提取文件名
set "SHA_VALUE="

:: 去除引号
set "CLEAN_FROM_LINE=!FROM_LINE:"=!"

:: 检查是否是绝对路径
if "!CLEAN_FROM_LINE:~1,2!"==":\" (
    echo FROM行包含Windows绝对路径
    for %%f in ("!CLEAN_FROM_LINE!") do (
        set "SHA_VALUE=%%~nxf"
        echo 从绝对路径中提取的文件名: !SHA_VALUE!
    )
) else (
    :: 尝试其他格式
    echo FROM行不是绝对路径,尝试其他格式提取
    
    :: 尝试提取sha256-开头的文件名部分
    if "!CLEAN_FROM_LINE:~0,7!"=="sha256-" (
        set "SHA_VALUE=!CLEAN_FROM_LINE!"
        echo 直接使用sha256值: !SHA_VALUE!
    ) else (
        :: 尝试Windows路径格式提取文件名
        for /f "tokens=*" %%a in ("!CLEAN_FROM_LINE!") do (
            set "SHA_VALUE=%%~nxa"
            echo 尝试Windows路径提取: !SHA_VALUE!
        )
        
        :: 尝试UNIX风格路径格式提取最后部分
        if "!SHA_VALUE!"=="" (
            for /f "tokens=* delims=/" %%a in ("!CLEAN_FROM_LINE!") do (
                set "LAST_PATH_PART=%%a"
            )
            set "SHA_VALUE=!LAST_PATH_PART!"
            echo 尝试UNIX路径提取: !SHA_VALUE!
        )
    )
)

echo 最终提取的模型哈希值: !SHA_VALUE!

:: 尝试在Ollama模型目录中查找模型文件
set "FOUND_MODEL=0"
set "MODEL_PATH="

:: 首先在直接路径中查找
if exist "!FROM_LINE!" (
    set "MODEL_PATH=!FROM_LINE!"
    set "FOUND_MODEL=1"
    echo 发现模型文件: !MODEL_PATH!
)

:: 然后在blob目录中查找
if "!FOUND_MODEL!"=="0" (
    if exist "%OLLAMA_MODELS_PATH%\blobs\!SHA_VALUE!" (
        set "MODEL_PATH=%OLLAMA_MODELS_PATH%\blobs\!SHA_VALUE!"
        set "FOUND_MODEL=1"
        echo 发现模型文件: !MODEL_PATH!
    )
)

:: 最后搜索整个blob目录查找匹配文件
if "!FOUND_MODEL!"=="0" (
    echo 搜索blob目录寻找模型文件...
    for /f "tokens=*" %%f in ('dir /b "%OLLAMA_MODELS_PATH%\blobs\*" 2^>nul') do (
        if "%%f"=="!SHA_VALUE!" (
            set "MODEL_PATH=%OLLAMA_MODELS_PATH%\blobs\%%f"
            set "FOUND_MODEL=1"
            echo 发现模型文件: !MODEL_PATH!
        )
    )
)

:: 直接尝试使用FROM_LINE中的绝对路径
if "!FOUND_MODEL!"=="0" (
    echo 尝试直接使用FROM行中的绝对路径...
    set "DIRECT_PATH=!FROM_LINE!"
    :: 去除引号
    set "DIRECT_PATH=!DIRECT_PATH:"=!"
    if exist "!DIRECT_PATH!" (
        set "MODEL_PATH=!DIRECT_PATH!"
        set "FOUND_MODEL=1"
        for %%f in ("!DIRECT_PATH!") do set "SHA_VALUE=%%~nxf"
        echo 使用绝对路径找到模型文件: !MODEL_PATH!
    )
)

:: 复制模型文件
if "!FOUND_MODEL!"=="1" (
    echo 正在复制模型文件到: !MODEL_FOLDER!\!SHA_VALUE!
    copy "!MODEL_PATH!" "!MODEL_FOLDER!\!SHA_VALUE!" > nul
    
    :: 更新Modelfile中的路径
    echo 更新Modelfile中的模型路径...
    (
        for /f "tokens=*" %%a in ('type "!MODEL_FOLDER!\modelfile"') do (
            set "LINE=%%a"
            if "!LINE:~0,4!"=="FROM" (
                echo FROM !SHA_VALUE!
            ) else (
                echo %%a
            )
        )
    ) > "!MODEL_FOLDER!\modelfile.new"
    move /y "!MODEL_FOLDER!\modelfile.new" "!MODEL_FOLDER!\modelfile" > nul
    
    echo.
    echo 导出成功!模型已导出到:
    echo !MODEL_FOLDER!\modelfile
    echo !MODEL_FOLDER!\!SHA_VALUE!
    echo.
    echo 如需导入该模型,请记住这两个文件都必须存在。
    
    :: 创建自动导入脚本
    echo 创建自动导入脚本...
    (
        echo @echo off
		echo chcp 65001 ^> nul
        echo echo 正在导入模型: !ORIGINAL_MODEL_NAME!
        echo ollama create !ORIGINAL_MODEL_NAME! -f modelfile
        echo echo 导入完成!
        echo pause
    ) > "!MODEL_FOLDER!\import.bat"
    echo 已创建自动导入脚本: !MODEL_FOLDER!\import.bat
) else (
    echo 错误: 无法找到模型文件。
    echo 请检查Ollama安装和模型是否完整。
)

pause
goto MAIN_MENU

:IMPORT_MENU
cls
echo ====================================
echo         Import Ollama Models
echo ====================================
echo.

:: Set import path
set "IMPORT_PATH=%DEFAULT_IMPORT_PATH%"
set /p CUSTOM_PATH="Enter import path [default: %IMPORT_PATH%]: "
if not "%CUSTOM_PATH%"=="" set "IMPORT_PATH=%CUSTOM_PATH%"

:: Check import directory
if not exist "%IMPORT_PATH%" (
    echo Error: Import directory does not exist!
    pause
    goto MAIN_MENU
)

:: Find available model directories
echo.
echo Models found in %IMPORT_PATH%:
echo -----------------------------------
set MODEL_COUNT=0

:: Check for subdirectories containing modelfile
for /d %%d in ("%IMPORT_PATH%\*") do (
    if exist "%%d\modelfile" (
        set /a MODEL_COUNT+=1
        set "MODEL_DIR_!MODEL_COUNT!=%%d"
        set "MODEL_NAME_!MODEL_COUNT!=%%~nxd"
        echo !MODEL_COUNT!. %%~nxd
    )
)

:: If no model directories found, check root directory
if %MODEL_COUNT% EQU 0 (
    if exist "%IMPORT_PATH%\modelfile" (
        set /a MODEL_COUNT+=1
        set "MODEL_DIR_1=%IMPORT_PATH%"
        for %%f in ("%IMPORT_PATH%") do set "MODEL_NAME_1=%%~nxf"
        echo 1. %MODEL_NAME_1% ^(root directory^)
    )
)

if %MODEL_COUNT% EQU 0 (
    echo No models found.
    echo Please ensure the import directory contains model folders with modelfile files.
    pause
    goto MAIN_MENU
)

:: Select model
echo.
set /p MODEL_SELECT="Select model to import (1-%MODEL_COUNT%): "

:: Validate input
if %MODEL_SELECT% LSS 1 goto IMPORT_MENU
if %MODEL_SELECT% GTR %MODEL_COUNT% goto IMPORT_MENU

:: Get selected model directory
set "SELECTED_DIR=!MODEL_DIR_%MODEL_SELECT%!"
set "SELECTED_NAME=!MODEL_NAME_%MODEL_SELECT%!"

echo.
echo Preparing to import model: %SELECTED_NAME%
echo Using directory: %SELECTED_DIR%

:: Prepare model name from folder name
set "MODEL_TO_CREATE=!SELECTED_NAME!"
:: Replace only first underscore with colon
set "FIRST_PART="
set "SECOND_PART="
for /f "tokens=1,* delims=_" %%a in ("!MODEL_TO_CREATE!") do (
    set "FIRST_PART=%%a"
    set "SECOND_PART=%%b"
)
if not "!SECOND_PART!"=="" (
    set "MODEL_TO_CREATE=!FIRST_PART!:!SECOND_PART!"
)

echo.
echo Will create model as: !MODEL_TO_CREATE!
echo Press any key to continue, or Ctrl+C to cancel...
pause > nul

:: Find model file
set "FOUND_BLOB=0"
set "BLOB_PATH="

:: Check current directory for SHA files
for /f "tokens=* delims=" %%a in ('dir /b "%SELECTED_DIR%\sha256-*" 2^>nul') do (
    set "BLOB_PATH=%SELECTED_DIR%\%%a"
    set "BLOB_NAME=%%a"
    set "FOUND_BLOB=1"
)

if "!FOUND_BLOB!"=="0" (
    :: Try to find any large file that might be the model
    for /f "tokens=*" %%a in ('dir /b /a-d /s "%SELECTED_DIR%\*" 2^>nul ^| findstr /v "modelfile import.bat import.ps1"') do (
        set "FILE_PATH=%%a"
        set "FILE_NAME=%%~nxa"
        set "FILE_SIZE=%%~za"
        
        :: Check if file is large (>100MB)
        if !FILE_SIZE! GTR 104857600 (
            set "BLOB_PATH=!FILE_PATH!"
            set "BLOB_NAME=!FILE_NAME!"
            set "FOUND_BLOB=1"
            echo Found large file that is likely the model: !BLOB_NAME!
        )
    )
)

if "!FOUND_BLOB!"=="0" (
    echo Error: Cannot find model blob file.
    echo Please ensure the model directory contains the model file.
    pause
    goto MAIN_MENU
)

echo Found model file: !BLOB_PATH!

:: Create a temporary directory for the import
set "TEMP_DIR=%TEMP%\ollama_import_%RANDOM%"
mkdir "%TEMP_DIR%" 2>nul

:: Copy necessary files to temp directory
echo Preparing files for import...
copy "!BLOB_PATH!" "%TEMP_DIR%\!BLOB_NAME!" > nul
copy "%SELECTED_DIR%\modelfile" "%TEMP_DIR%\modelfile" > nul

:: Create temporary Modelfile pointing to the copied blob
echo FROM !BLOB_NAME! > "%TEMP_DIR%\modelfile.new"
for /f "skip=1 tokens=*" %%a in ('type "%TEMP_DIR%\modelfile"') do (
    echo %%a >> "%TEMP_DIR%\modelfile.new"
)
move /y "%TEMP_DIR%\modelfile.new" "%TEMP_DIR%\modelfile" > nul

:: Change to temp directory for import
cd /d "%TEMP_DIR%"

:: Import the model
echo.
echo Importing model: !MODEL_TO_CREATE!
echo Command: ollama create !MODEL_TO_CREATE! -f modelfile
echo.
echo Processing... (this may take a while)

:: Run the import with error handling
ollama create !MODEL_TO_CREATE! -f modelfile > import_log.txt 2>&1
set IMPORT_ERROR=%ERRORLEVEL%

:: Display the log
type import_log.txt

:: Check for errors
if %IMPORT_ERROR% NEQ 0 (
    echo.
    echo Import failed! Please check the error messages above.
    echo Full log saved to: "%TEMP_DIR%\import_log.txt"
    echo.
    echo Press any key to return to menu...
    pause > nul
) else (
    echo.
    echo Import completed successfully!
    echo You can now use 'ollama run !MODEL_TO_CREATE!' to run this model.
    echo.
    echo Press any key to return to menu...
    pause > nul
    
    :: Clean up temp directory if successful
    cd /d "%~dp0"
    rd /s /q "%TEMP_DIR%" 2>nul
)

goto MAIN_MENU

:EXIT_SCRIPT
echo 感谢使用Ollama模型导入导出工具!
timeout /t 2 > nul
exit /b 0

3.2 Linux脚本(ollama_backup.sh)
 

#!/bin/bash

# Ollama模型导入导出工具 (Debian Linux版)
# 适用于Debian/Ubuntu系统

# 设置颜色
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m' # 恢复默认颜色

# 设置默认路径
DEFAULT_EXPORT_PATH="/home/rayse/ollama/ollama_backup"
DEFAULT_IMPORT_PATH="/home/rayse/ollama/ollama_backup"
OLLAMA_MODELS_PATH="/home/rayse/ollama/models"
OLLAMA_BLOBS_PATH="/home/rayse/ollama/models/blobs"

# 确保目录存在
mkdir -p "$DEFAULT_EXPORT_PATH" 2>/dev/null

# 显示标题
show_title() {
    clear
    echo -e "${GREEN}=====================================${NC}"
    echo -e "${GREEN}      Ollama 模型导入导出工具       ${NC}"
    echo -e "${GREEN}=====================================${NC}"
    echo
}

# 主菜单
main_menu() {
    show_title
    echo -e "请选择操作:"
    echo -e "[${YELLOW}1${NC}] 导出/备份模型"
    echo -e "[${YELLOW}2${NC}] 导入模型"
    echo -e "[${YELLOW}3${NC}] 退出"
    echo
    read -p "请输入选项 (1-3): " CHOICE
    
    case $CHOICE in
        1) export_menu ;;
        2) import_menu ;;
        3) exit_script ;;
        *) main_menu ;;
    esac
}

# 导出菜单
export_menu() {
    show_title
    echo -e "${BLUE}导出/备份 Ollama 模型${NC}"
    echo -e "${GREEN}=====================================${NC}"
    echo
    
    # 设置导出路径
    EXPORT_PATH="$DEFAULT_EXPORT_PATH"
    read -p "请输入导出路径 [默认: $EXPORT_PATH]: " CUSTOM_PATH
    if [ ! -z "$CUSTOM_PATH" ]; then
        EXPORT_PATH="$CUSTOM_PATH"
    fi
    
    # 确保导出目录存在
    mkdir -p "$EXPORT_PATH" 2>/dev/null
    
    # 列出可用模型
    echo
    echo -e "${BLUE}可用的 Ollama 模型:${NC}"
    echo -e "${GREEN}-------------------${NC}"
    
    # 获取模型列表
    MODEL_LIST=$(ollama list)
    MODEL_COUNT=0
    
    # 跳过标题行
    MODELS=$(echo "$MODEL_LIST" | sed '1d')
    if [ -z "$MODELS" ]; then
        echo "没有找到可用的模型。"
        read -p "按 Enter 键返回主菜单..." dummy
        main_menu
        return
    fi
    
    # 建立模型数组
    declare -a MODEL_ARRAY
    while IFS= read -r line; do
        if [ ! -z "$line" ]; then
            MODEL_COUNT=$((MODEL_COUNT + 1))
            MODEL_ARRAY[$MODEL_COUNT]="$line"
            echo -e "${YELLOW}$MODEL_COUNT${NC}. $line"
        fi
    done <<< "$MODELS"
    
    # 选择模型
    echo
    read -p "请选择要导出的模型 (1-$MODEL_COUNT): " MODEL_SELECT
    
    # 验证输入
    if ! [[ "$MODEL_SELECT" =~ ^[0-9]+$ ]] || [ "$MODEL_SELECT" -lt 1 ] || [ "$MODEL_SELECT" -gt "$MODEL_COUNT" ]; then
        echo -e "${RED}无效的选择,请重试${NC}"
        sleep 2
        export_menu
        return
    fi
    
    # 获取选中的模型
    SELECTED_MODEL_LINE="${MODEL_ARRAY[$MODEL_SELECT]}"
    ORIGINAL_MODEL_NAME=$(echo "$SELECTED_MODEL_LINE" | awk '{print $1}')
    
    # 为模型创建一个安全的文件夹名
    SAFE_MODEL_NAME=$(echo "$ORIGINAL_MODEL_NAME" | tr ':' '_')
    MODEL_FOLDER="$EXPORT_PATH/$SAFE_MODEL_NAME"
    
    # 创建模型专用文件夹
    echo "创建模型文件夹: $MODEL_FOLDER"
    mkdir -p "$MODEL_FOLDER"
    
    # 导出 Modelfile
    echo "正在导出 Modelfile..."
    ollama show "$ORIGINAL_MODEL_NAME" --modelfile > "$MODEL_FOLDER/modelfile"
    if [ ! -f "$MODEL_FOLDER/modelfile" ]; then
        echo -e "${RED}错误: 无法导出 Modelfile!${NC}"
        read -p "按 Enter 键返回主菜单..." dummy
        main_menu
        return
    fi
    
    # 从 Modelfile 中提取 SHA 值
    echo "正在查找模型文件路径..."
    FROM_LINE=$(grep -m 1 "^FROM " "$MODEL_FOLDER/modelfile" | cut -d ' ' -f 2-)
    
    if [ -z "$FROM_LINE" ]; then
        echo -e "${YELLOW}警告: 在 Modelfile 中未找到 FROM 行${NC}"
        read -p "按 Enter 键返回主菜单..." dummy
        main_menu
        return
    fi
    
    echo "提取的模型文件路径: $FROM_LINE"
    
    # 提取 SHA 值
    if [[ "$FROM_LINE" == sha256* ]]; then
        SHA_VALUE="$FROM_LINE"
        echo "使用 SHA 值: $SHA_VALUE"
    elif [[ "$FROM_LINE" == /* ]]; then
        # 绝对路径
        SHA_VALUE=$(basename "$FROM_LINE")
        echo "从绝对路径提取的文件名: $SHA_VALUE"
    else
        # 其他格式
        SHA_VALUE=$(basename "$FROM_LINE")
        echo "提取的文件名: $SHA_VALUE"
    fi
    
    echo "最终提取的模型哈希值: $SHA_VALUE"
    
    # 查找模型文件
    FOUND_MODEL=0
    MODEL_PATH=""
    
    # 尝试直接路径
    if [ -f "$FROM_LINE" ]; then
        MODEL_PATH="$FROM_LINE"
        FOUND_MODEL=1
        echo "发现模型文件: $MODEL_PATH"
    fi
    
    # 尝试 blob 目录
    if [ "$FOUND_MODEL" -eq 0 ] && [ -f "$OLLAMA_BLOBS_PATH/$SHA_VALUE" ]; then
        MODEL_PATH="$OLLAMA_BLOBS_PATH/$SHA_VALUE"
        FOUND_MODEL=1
        echo "发现模型文件: $MODEL_PATH"
    fi
    
    # 搜索整个 blob 目录
    if [ "$FOUND_MODEL" -eq 0 ]; then
        echo "搜索 blob 目录寻找模型文件..."
        for file in "$OLLAMA_BLOBS_PATH"/*; do
            if [ -f "$file" ] && [ "$(basename "$file")" = "$SHA_VALUE" ]; then
                MODEL_PATH="$file"
                FOUND_MODEL=1
                echo "发现模型文件: $MODEL_PATH"
                break
            fi
        done
    fi
    
    # 复制模型文件
    if [ "$FOUND_MODEL" -eq 1 ]; then
        echo "正在复制模型文件到: $MODEL_FOLDER/$SHA_VALUE"
        cp "$MODEL_PATH" "$MODEL_FOLDER/$SHA_VALUE"
        
        # 更新 Modelfile 中的路径
        echo "更新 Modelfile 中的模型路径..."
        sed -i "s|^FROM .*|FROM $SHA_VALUE|" "$MODEL_FOLDER/modelfile"
        
        echo
        echo -e "${GREEN}导出成功!${NC}模型已导出到:"
        echo "$MODEL_FOLDER/modelfile"
        echo "$MODEL_FOLDER/$SHA_VALUE"
        echo
        
        # 创建导入脚本
        echo "创建导入脚本..."
        
        # 中文版导入脚本
        cat > "$MODEL_FOLDER/import.sh" << EOF
#!/bin/bash
echo "正在导入模型: $ORIGINAL_MODEL_NAME"
ollama create "$ORIGINAL_MODEL_NAME" -f modelfile
echo "导入完成!"
echo "按任意键退出..."
read -n 1
EOF
        
        # 英文版导入脚本
        cat > "$MODEL_FOLDER/import_en.sh" << EOF
#!/bin/bash
# Ollama Model Import Script
echo "========================================="
echo "     Ollama Model Import Tool"
echo "========================================="

# Get the current directory
CURRENT_DIR="\$(dirname "\$(readlink -f "\$0")")"

# Get the folder name
FOLDER_NAME="\$(basename "\$CURRENT_DIR")"

# Convert underscore to colon for model name
MODEL_NAME="\$(echo "\$FOLDER_NAME" | sed 's/_/:/' | cut -d '_' -f 1-2)"

echo
echo "Importing model: \$MODEL_NAME"
echo "Model file location: \$CURRENT_DIR/modelfile"
echo

# Check if modelfile exists
if [ ! -f "\$CURRENT_DIR/modelfile" ]; then
    echo "ERROR: Cannot find modelfile in the current directory!"
    echo "Current directory: \$CURRENT_DIR"
    read -p "Press Enter to exit..." dummy
    exit 1
fi

# Try to import the model
echo "Executing: ollama create \$MODEL_NAME -f modelfile"
echo
ollama create "\$MODEL_NAME" -f modelfile

if [ \$? -ne 0 ]; then
    echo
    echo "Import failed! Please check the error messages above."
else
    echo
    echo "Import completed successfully!"
    echo "You can now use 'ollama run \$MODEL_NAME' to run this model."
fi

echo
read -p "Press Enter to exit..." dummy
EOF
        
        # 设置可执行权限
        chmod +x "$MODEL_FOLDER/import.sh"
        chmod +x "$MODEL_FOLDER/import_en.sh"
        
        echo "已创建导入脚本:"
        echo "- 中文版: $MODEL_FOLDER/import.sh"
        echo "- 英文版: $MODEL_FOLDER/import_en.sh"
    else
        echo -e "${RED}错误: 无法找到模型文件。${NC}"
        echo "请检查 Ollama 安装和模型是否完整。"
    fi
    
    read -p "按 Enter 键返回主菜单..." dummy
    main_menu
}

# 导入菜单
import_menu() {
    show_title
    echo -e "${BLUE}导入 Ollama 模型${NC}"
    echo -e "${GREEN}=====================================${NC}"
    echo
    
    # 设置导入路径
    IMPORT_PATH="$DEFAULT_IMPORT_PATH"
    read -p "请输入导入路径 [默认: $IMPORT_PATH]: " CUSTOM_PATH
    if [ ! -z "$CUSTOM_PATH" ]; then
        IMPORT_PATH="$CUSTOM_PATH"
    fi
    
    # 检查导入目录
    if [ ! -d "$IMPORT_PATH" ]; then
        echo -e "${RED}错误: 导入目录不存在!${NC}"
        read -p "按 Enter 键返回主菜单..." dummy
        main_menu
        return
    fi
    
    # 查找可用的模型目录
    echo
    echo -e "${BLUE}在 $IMPORT_PATH 中找到的模型:${NC}"
    echo -e "${GREEN}-----------------------------------${NC}"
    
    # 扫描包含 modelfile 的目录
    MODEL_COUNT=0
    declare -a MODEL_DIRS
    declare -a MODEL_NAMES
    
    for dir in "$IMPORT_PATH"/*; do
        if [ -d "$dir" ] && [ -f "$dir/modelfile" ]; then
            MODEL_COUNT=$((MODEL_COUNT + 1))
            MODEL_DIRS[$MODEL_COUNT]="$dir"
            MODEL_NAMES[$MODEL_COUNT]=$(basename "$dir")
            echo -e "${YELLOW}$MODEL_COUNT${NC}. ${MODEL_NAMES[$MODEL_COUNT]}"
        fi
    done
    
    # 检查根目录
    if [ "$MODEL_COUNT" -eq 0 ] && [ -f "$IMPORT_PATH/modelfile" ]; then
        MODEL_COUNT=1
        MODEL_DIRS[1]="$IMPORT_PATH"
        MODEL_NAMES[1]=$(basename "$IMPORT_PATH")
        echo -e "${YELLOW}1${NC}. ${MODEL_NAMES[1]} (根目录)"
    fi
    
    if [ "$MODEL_COUNT" -eq 0 ]; then
        echo "没有找到可用的模型。"
        echo "请确保导入目录中包含模型文件夹,且每个文件夹内有 modelfile 文件。"
        read -p "按 Enter 键返回主菜单..." dummy
        main_menu
        return
    fi
    
    # 选择模型
    echo
    read -p "请选择要导入的模型 (1-$MODEL_COUNT): " MODEL_SELECT
    
    # 验证输入
    if ! [[ "$MODEL_SELECT" =~ ^[0-9]+$ ]] || [ "$MODEL_SELECT" -lt 1 ] || [ "$MODEL_SELECT" -gt "$MODEL_COUNT" ]; then
        echo -e "${RED}无效的选择,请重试${NC}"
        sleep 2
        import_menu
        return
    fi
    
    # 获取选中的模型目录
    SELECTED_DIR="${MODEL_DIRS[$MODEL_SELECT]}"
    SELECTED_NAME="${MODEL_NAMES[$MODEL_SELECT]}"
    
    echo
    echo "准备导入模型: $SELECTED_NAME"
    echo "使用目录: $SELECTED_DIR"
    
    # 准备模型名称(将下划线转回冒号)
    MODEL_TO_CREATE="$SELECTED_NAME"
    # 只替换第一个下划线为冒号
    MODEL_TO_CREATE=$(echo "$MODEL_TO_CREATE" | sed 's/_/:/' | cut -d '_' -f 1-2)
    
    echo
    echo "将创建模型为: $MODEL_TO_CREATE"
    read -p "按 Enter 键继续,或按 Ctrl+C 取消..." dummy
    
    # 查找模型文件
    FOUND_BLOB=0
    BLOB_PATH=""
    BLOB_NAME=""
    
    # 检查SHA文件
    for file in "$SELECTED_DIR"/*; do
        if [ -f "$file" ] && [ "$(basename "$file")" != "modelfile" ] && 
           [ "$(basename "$file")" != "import.sh" ] && [ "$(basename "$file")" != "import_en.sh" ]; then
            # 检查文件大小 (大于10MB的文件可能是模型文件)
            FILE_SIZE=$(stat -c%s "$file")
            if [ "$FILE_SIZE" -gt 10485760 ]; then
                BLOB_PATH="$file"
                BLOB_NAME=$(basename "$file")
                FOUND_BLOB=1
                echo "找到可能的模型文件: $BLOB_NAME ($(( FILE_SIZE / 1048576 )) MB)"
                break
            fi
        fi
    done
    
    if [ "$FOUND_BLOB" -eq 0 ]; then
        echo -e "${RED}错误: 无法找到模型文件。${NC}"
        echo "请确保模型目录中包含模型文件(通常是一个大文件)。"
        read -p "按 Enter 键返回主菜单..." dummy
        main_menu
        return
    fi
    
    echo "找到模型文件: $BLOB_PATH"
    
    # 创建临时目录
    TEMP_DIR=$(mktemp -d)
    
    # 复制必要文件到临时目录
    echo "准备导入文件..."
    cp "$BLOB_PATH" "$TEMP_DIR/$BLOB_NAME"
    cp "$SELECTED_DIR/modelfile" "$TEMP_DIR/modelfile"
    
    # 更新Modelfile
    sed -i "1s|^FROM .*|FROM $BLOB_NAME|" "$TEMP_DIR/modelfile"
    
    # 进入临时目录
    cd "$TEMP_DIR"
    
    # 导入模型
    echo
    echo "导入模型: $MODEL_TO_CREATE"
    echo "命令: ollama create $MODEL_TO_CREATE -f modelfile"
    echo
    echo "处理中... (可能需要一些时间)"
    
    # 运行导入
    ollama create "$MODEL_TO_CREATE" -f modelfile
    IMPORT_ERROR=$?
    
    # 检查错误
    if [ "$IMPORT_ERROR" -ne 0 ]; then
        echo
        echo -e "${RED}导入失败!${NC}请检查上述错误信息。"
    else
        echo
        echo -e "${GREEN}导入完成!${NC}"
        echo "你现在可以使用 'ollama run $MODEL_TO_CREATE' 来运行该模型。"
        
        # 清理临时目录
        rm -rf "$TEMP_DIR"
    fi
    
    echo
    read -p "按 Enter 键返回主菜单..." dummy
    main_menu
}

# 退出脚本
exit_script() {
    echo "感谢使用 Ollama 模型导入导出工具!"
    sleep 1
    exit 0
}

# 启动主菜单
main_menu

四、使用指南
 

4.1 准备工作

  1. 创建备份目录(示例路径可自定义)
     

  2. 修改脚本中的配置参数:

    #模型导出路径(备份的模型会放到这)
    DEFAULT_EXPORT_PATH="/home/rayse/ollama/ollama_backup"
    #模型恢复路径(需要的模型会放到这,然后脚本识别一件恢复)
    DEFAULT_IMPORT_PATH="/home/rayse/ollama/ollama_backup"
    #模型保存的路径
    OLLAMA_MODELS_PATH="/home/rayse/ollama/models"
    #模型文件路径
    OLLAMA_BLOBS_PATH="/home/rayse/ollama/models/blobs"
  3. 执行脚本
    windows双击bat脚本即可
    Linux

    #授权
    chmod +x ollama_backup.sh
    #执行脚本
    ./ollama_backup.sh
    效果

    备份:
    恢复



     

    五、注意事项

  4. 路径有效性:确保脚本中配置的路径存在且可写

  5. 权限问题:Linux系统需要Ollama服务权限

  6. 磁盘空间:大模型文件需要预留足够空间

  7. 版本兼容:建议Ollama版本保持一致



  8. 技术交流欢迎在评论区留言!如果遇到脚本执行问题,请附上报错信息与系统环境说明~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值