adaptive_rag / KAGGLE_LOAD_OLLAMA.py
lanny xu
resolve conflict
ee37277
raw
history blame
9.13 kB
"""
Kaggle Ollama 加载脚本
从 Kaggle Dataset 快速加载 Ollama 和模型,无需重新下载
前置条件:
1. 已使用 KAGGLE_SAVE_OLLAMA.py 创建备份
2. 已在 Kaggle 上传 Dataset
3. 已在 Notebook 中添加该 Dataset
使用方法:
在 Kaggle Notebook 第一个单元格运行:
exec(open('/kaggle/working/adaptive_RAG/KAGGLE_LOAD_OLLAMA.py').read())
"""
import os
import subprocess
import tarfile
import shutil
import time
print("="*70)
print("📦 从 Dataset 加载 Ollama(快速启动)")
print("="*70)
# ==================== 配置 ====================
# 修改为你的 Dataset 名称
# 常见名称: ollama-mistral-backup, ollama-phi-backup, ollama-backup 等
DATASET_NAME = "ollama-mistral-backup" # 👈 修改这里为你的实际 Dataset 名称
DATASET_PATH = f"/kaggle/input/{DATASET_NAME}"
print(f"💡 提示: 如果 Dataset 不存在,请检查:")
print(f" 1. Dataset 是否已添加到 Notebook")
print(f" 2. Dataset 名称是否正确")
print(f" 3. 可用的 Datasets:")
import os
if os.path.exists("/kaggle/input"):
available = os.listdir("/kaggle/input")
if available:
for ds in available:
print(f" • {ds}")
else:
print(f" (无)")
print()
print(f"\n📋 配置:")
print(f" Dataset 路径: {DATASET_PATH}")
# ==================== 检查 Dataset ====================
print(f"\n🔍 步骤 1/5: 检查 Dataset...")
if not os.path.exists(DATASET_PATH):
print(f" ❌ Dataset 不存在: {DATASET_PATH}")
print(f"\n💡 请检查:")
print(f" 1. Dataset 是否已添加到 Notebook")
print(f" 2. Dataset 名称是否正确")
print(f" 3. 可用的 Datasets:")
if os.path.exists("/kaggle/input"):
for item in os.listdir("/kaggle/input"):
print(f" • {item}")
print(f"\n📝 如何添加 Dataset:")
print(f" 1. 点击右侧 'Add data' 按钮")
print(f" 2. 选择 'Your Datasets'")
print(f" 3. 找到你的 ollama 备份 Dataset")
print(f" 4. 点击 'Add'")
exit(1)
print(f" ✅ Dataset 存在")
# 列出 Dataset 内容
print(f"\n Dataset 内容:")
for item in os.listdir(DATASET_PATH):
item_path = os.path.join(DATASET_PATH, item)
if os.path.isfile(item_path):
size = os.path.getsize(item_path)
size_str = f"{size / (1024**3):.2f} GB" if size > 1024**3 else f"{size / (1024**2):.2f} MB"
print(f" • {item}: {size_str}")
# ==================== 安装 Ollama 二进制文件 ====================
print(f"\n🔧 步骤 2/5: 安装 Ollama 二进制文件...")
ollama_bin_source = os.path.join(DATASET_PATH, "ollama")
if os.path.exists(ollama_bin_source):
# 先停止可能正在运行的 Ollama 服务
print(f" 🛑 检查并停止现有 Ollama 进程...")
subprocess.run(['pkill', '-9', 'ollama'], capture_output=True)
time.sleep(2)
# 复制到系统路径
ollama_bin_dest = "/usr/local/bin/ollama"
try:
shutil.copy2(ollama_bin_source, ollama_bin_dest)
# 设置执行权限
os.chmod(ollama_bin_dest, 0o755)
print(f" ✅ Ollama 已安装到: {ollama_bin_dest}")
# 验证版本
version_result = subprocess.run(['ollama', '--version'], capture_output=True, text=True)
if version_result.returncode == 0:
print(f" 📌 {version_result.stdout.strip()}")
except OSError as e:
if "Text file busy" in str(e):
print(f" ⚠️ 文件被占用,尝试强制停止...")
subprocess.run(['killall', '-9', 'ollama'], capture_output=True)
time.sleep(3)
# 重试
shutil.copy2(ollama_bin_source, ollama_bin_dest)
os.chmod(ollama_bin_dest, 0o755)
print(f" ✅ Ollama 已安装(重试成功)")
else:
raise
else:
print(f" ❌ 未找到 Ollama 二进制文件")
exit(1)
# ==================== 解压模型文件 ====================
print(f"\n📦 步骤 3/5: 恢复模型文件...")
models_archive = os.path.join(DATASET_PATH, "ollama_models.tar.gz")
ollama_home = os.path.expanduser("~")
# 检查是否有压缩包
if os.path.exists(models_archive):
# 情况1: 有压缩包,需要解压
print(f" 找到模型压缩包: {os.path.getsize(models_archive) / (1024**3):.2f} GB")
print(f" 📦 开始解压(这可能需要 10-30 秒)...")
start_time = time.time()
with tarfile.open(models_archive, 'r:gz') as tar:
tar.extractall(ollama_home) # 会自动创建 ~/.ollama 目录
elapsed = time.time() - start_time
print(f" ✅ 解压完成(耗时: {int(elapsed)}秒)")
else:
# 情况2: 没有压缩包,检查是否已解压
print(f" ⚠️ 未找到压缩包,检查是否有解压后的文件...")
# 检查常见的解压后文件/目录
possible_sources = [
os.path.join(DATASET_PATH, ".ollama"), # 直接在根目录
os.path.join(DATASET_PATH, "ollama_model", ".ollama"), # 在 ollama_model 文件夹内(嵌套结构)
os.path.join(DATASET_PATH, "ollama_models", ".ollama"), # 在 ollama_models 文件夹内
os.path.join(DATASET_PATH, "ollama"), # 备用路径
os.path.join(DATASET_PATH, "models") # 备用路径
]
found = False
for source in possible_sources:
if os.path.exists(source):
print(f" ✅ 找到解压后的目录: {source}")
# 确定目标目录
if source.endswith(".ollama"):
# 直接复制整个 .ollama 目录
dest = os.path.join(ollama_home, ".ollama")
else:
# 创建 .ollama/models 目录
dest = os.path.join(ollama_home, ".ollama", "models")
os.makedirs(os.path.dirname(dest), exist_ok=True)
print(f" 📋 复制到: {dest}")
# 复制文件
if os.path.isdir(source):
shutil.copytree(source, dest, dirs_exist_ok=True)
else:
shutil.copy2(source, dest)
found = True
break
if not found:
print(f" ❌ 未找到模型文件")
print(f"\n Dataset 内容:")
for item in os.listdir(DATASET_PATH):
print(f" • {item}")
exit(1)
# 检查模型目录
models_dir = os.path.join(ollama_home, ".ollama")
if os.path.exists(models_dir):
total_size = sum(
os.path.getsize(os.path.join(dirpath, filename))
for dirpath, dirnames, filenames in os.walk(models_dir)
for filename in filenames
)
print(f" 📊 模型总大小: {total_size / (1024**3):.2f} GB")
else:
print(f" ❌ 未找到模型压缩包")
exit(1)
# ==================== 启动 Ollama 服务 ====================
print(f"\n🚀 步骤 4/5: 启动 Ollama 服务...")
# 检查是否已运行
ps_check = subprocess.run(['pgrep', '-f', 'ollama serve'], capture_output=True)
if ps_check.returncode == 0:
print(f" ✅ Ollama 服务已在运行")
else:
print(f" 🔄 启动服务...")
subprocess.Popen(
['ollama', 'serve'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
print(f" ⏳ 等待服务启动(15秒)...")
time.sleep(15)
# 验证服务
import requests
try:
response = requests.get('http://localhost:11434/api/tags', timeout=10)
if response.status_code == 200:
print(f" ✅ Ollama 服务运行正常")
except Exception as e:
print(f" ⚠️ 服务验证失败: {e}")
print(f" 但可能仍在启动中...")
# ==================== 验证模型 ====================
print(f"\n✅ 步骤 5/5: 验证模型...")
list_result = subprocess.run(['ollama', 'list'], capture_output=True, text=True)
print(f"\n 可用模型:")
print(f" {list_result.stdout}")
# ==================== 完成 ====================
print("="*70)
print("✅ Ollama 加载完成!")
print("="*70)
print(f"\n📊 加载总结:")
print(f" • Ollama 服务: ✅ 运行中")
print(f" • 模型: ✅ 已加载")
print(f" • 总耗时: < 1 分钟")
print(f"\n💡 对比:")
print(f" • 传统方式: 5-10 分钟(重新下载)")
print(f" • Dataset 方式: < 1 分钟(直接加载)")
print(f" • 节省时间: 约 90%!")
print(f"\n🧪 快速测试:")
print(f" 在新单元格运行:")
print(f" !ollama run mistral 'Hi, respond in one word'")
print(f"\n📝 下一步:")
print(f" 继续运行你的 GraphRAG 索引:")
print(f"""
from document_processor import DocumentProcessor
from graph_indexer import GraphRAGIndexer
processor = DocumentProcessor()
vectorstore, retriever, doc_splits = processor.setup_knowledge_base(enable_graphrag=True)
indexer = GraphRAGIndexer(async_batch_size=8)
graph = indexer.index_documents(doc_splits)
""")
print("\n" + "="*70)