模型管理

有效管理模型是使用 Ollama 的重要技能,这一章我们学习模型的各种管理操作。

模型下载

命令行下载

# 下载默认标签
ollama pull llama3.2

# 下载特定版本
ollama pull llama3.2:3b
ollama pull llama3.2:1b

# 下载量化版本
ollama pull llama3.2:3b-q4_K_M

API 下载

import ollama

def pull_model(name):
    for progress in ollama.pull(name, stream=True):
        if 'completed' in progress and 'total' in progress:
            percent = progress['completed'] / progress['total'] * 100
            print(f"\r下载进度: {percent:.1f}%", end='', flush=True)
        else:
            print(f"\n{progress.get('status', '')}")
    
    print(f"\n模型 {name} 下载完成")

pull_model('llama3.2')

批量下载

models = ['llama3.2', 'mistral:7b', 'codellama', 'nomic-embed-text']

for model in models:
    print(f"\n正在下载: {model}")
    pull_model(model)

查看模型

列出本地模型

ollama list

输出:

NAME            ID              SIZE    MODIFIED
llama3.2:latest abc123...       4.3 GB  2 hours ago
mistral:latest  def456...       3.8 GB  1 day ago

API 查询

import ollama

models = ollama.list()

for model in models['models']:
    size_gb = model['size'] / (1024 ** 3)
    print(f"{model['name']}: {size_gb:.2f} GB")
    print(f"  修改时间: {model['modified_at']}")
    print(f"  参数量: {model['details']['parameter_size']}")
    print(f"  量化: {model['details']['quantization_level']}")

查看模型详情

ollama show llama3.2

输出:

Model
  architecture        llama
  parameters          3.2B
  context length      131072
  embedding length    3072

Parameters
  stop    "<|start_header_id|>"
  stop    "<|end_header_id|>"
  stop    "<|eot_id|>"

Template
  {{ .System }}<|start_header_id|>user<|end_header_id|>
  {{ .Prompt }}<|eot_id|><|start_header_id|>assistant<|end_header_id|>

API 查询详情

import ollama

info = ollama.show('llama3.2')

print(f"模板:\n{info['template']}")
print(f"\n参数:\n{info['parameters']}")
print(f"\n模型信息:")
for key, value in info['model_info'].items():
    print(f"  {key}: {value}")

模型更新

更新模型

ollama pull llama3.2

如果模型有新版本,会自动更新。

检查更新

import requests

def check_update(model_name):
    # 获取本地版本
    local = ollama.show(model_name)
    local_digest = local.get('digest', '')
    
    # 获取远程版本
    response = requests.get(f"https://registry.ollama.ai/v2/library/{model_name}/manifests/latest")
    
    if response.status_code == 200:
        remote_digest = response.json().get('config', {}).get('digest', '')
        
        if local_digest != remote_digest:
            print(f"{model_name} 有新版本可用")
            return True
        else:
            print(f"{model_name} 已是最新版本")
            return False
    
    return None

check_update('llama3.2')

模型删除

命令行删除

ollama rm llama3.2
ollama rm llama3.2:3b

API 删除

import ollama

def delete_model(name):
    try:
        ollama.delete(name)
        print(f"模型 {name} 已删除")
    except Exception as e:
        print(f"删除失败: {e}")

delete_model('my-custom-model')

批量删除

def cleanup_old_versions(base_name, keep_latest=True):
    models = ollama.list()['models']
    
    to_delete = []
    for model in models:
        name = model['name']
        if name.startswith(base_name + ':'):
            tag = name.split(':')[1]
            if tag != 'latest' or not keep_latest:
                to_delete.append(name)
    
    for name in to_delete:
        print(f"删除: {name}")
        ollama.delete(name)
    
    print(f"已清理 {len(to_delete)} 个模型")

cleanup_old_versions('llama3.2')

模型复制

命令行复制

ollama cp llama3.2 llama3.2-backup

API 复制

import ollama

def copy_model(source, destination):
    try:
        ollama.copy(source, destination)
        print(f"已复制: {source} -> {destination}")
    except Exception as e:
        print(f"复制失败: {e}")

copy_model('llama3.2', 'llama3.2-backup')

模型推送

登录

ollama login

推送模型

ollama push myuser/my-model

API 推送

import ollama

def push_model(name):
    for progress in ollama.push(name, stream=True):
        print(progress.get('status', ''))
    
    print(f"模型 {name} 已推送")

push_model('myuser/my-model')

模型管理工具

import ollama
from datetime import datetime

class ModelManager:
    def __init__(self):
        pass
    
    def list_all(self):
        return ollama.list()['models']
    
    def get_size_summary(self):
        models = self.list_all()
        total_size = sum(m['size'] for m in models)
        
        return {
            'count': len(models),
            'total_size': total_size,
            'total_size_gb': total_size / (1024 ** 3)
        }
    
    def find_by_size(self, min_gb=0, max_gb=float('inf')):
        models = self.list_all()
        
        return [
            m for m in models
            if min_gb * (1024**3) <= m['size'] <= max_gb * (1024**3)
        ]
    
    def find_by_family(self, family):
        models = self.list_all()
        
        return [
            m for m in models
            if m['details']['family'].lower() == family.lower()
        ]
    
    def export_list(self, filename):
        models = self.list_all()
        
        with open(filename, 'w', encoding='utf-8') as f:
            for m in models:
                f.write(f"{m['name']}\n")
                f.write(f"  大小: {m['size'] / (1024**3):.2f} GB\n")
                f.write(f"  参数量: {m['details']['parameter_size']}\n")
                f.write(f"  量化: {m['details']['quantization_level']}\n")
                f.write("\n")
    
    def cleanup_unused(self, days=30):
        models = self.list_all()
        cutoff = datetime.now().timestamp() - days * 24 * 60 * 60
        
        deleted = []
        for m in models:
            modified = datetime.fromisoformat(m['modified_at'].replace('Z', '+00:00'))
            if modified.timestamp() < cutoff:
                ollama.delete(m['name'])
                deleted.append(m['name'])
        
        return deleted

# 使用
manager = ModelManager()

print("模型统计:")
summary = manager.get_size_summary()
print(f"  数量: {summary['count']}")
print(f"  总大小: {summary['total_size_gb']:.2f} GB")

print("\n大模型 (>5GB):")
large = manager.find_by_size(min_gb=5)
for m in large:
    print(f"  {m['name']}")

print("\nLlama 系列模型:")
llama_models = manager.find_by_family('llama')
for m in llama_models:
    print(f"  {m['name']}")