fix:1.修复模型文件被覆盖问题

This commit is contained in:
xiamuceer
2025-11-04 20:46:53 +08:00
parent 6d0b25186b
commit aaf4386f91
18 changed files with 60 additions and 22 deletions
-2
View File
@@ -43,8 +43,6 @@ backend/data/*.db
# ChromaDB数据库(不包含在镜像中,会在运行时生成)
backend/data/chroma_db/
# 注意:backend/data/models/ 目录需要打包(包含预下载的Embedding模型)
# 所以不要添加到 .dockerignore 中
# 日志文件
logs/
+1 -2
View File
@@ -102,8 +102,7 @@ dmypy.json
# Jupyter Notebook
.ipynb_checkpoints
data/*
!/data/models/
data/
docs/
data_old/
backend/migrate_all_databases.py
+4 -4
View File
@@ -53,11 +53,11 @@ COPY backend/ ./
COPY --from=frontend-builder /frontend/dist ./static
# 创建必要的目录
RUN mkdir -p /app/data /app/logs
RUN mkdir -p /app/data /app/logs /app/embedding
# 复制预下载的Embedding模型(如果存在
# 复制预下载的Embedding模型到独立目录(避免被docker-compose的data挂载覆盖
# 这样可以避免首次运行时联网下载约420MB的模型文件
COPY backend/data/models /app/data/models
COPY backend/data/models /app/embedding
# 复制环境变量示例文件
COPY backend/.env.example ./.env.example
@@ -74,7 +74,7 @@ ENV APP_PORT=8000
ENV TRANSFORMERS_OFFLINE=1
ENV HF_DATASETS_OFFLINE=1
ENV HF_HUB_OFFLINE=1
ENV SENTENCE_TRANSFORMERS_HOME=/app/data/models
ENV SENTENCE_TRANSFORMERS_HOME=/app/embedding
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
+55 -14
View File
@@ -10,11 +10,10 @@ import hashlib
logger = get_logger(__name__)
# 配置离线模式,避免联网检查
os.environ['TRANSFORMERS_OFFLINE'] = '1'
os.environ['HF_DATASETS_OFFLINE'] = '1'
os.environ['HF_HUB_OFFLINE'] = '1' # 禁用HuggingFace Hub联网
os.environ['SENTENCE_TRANSFORMERS_HOME'] = 'data/models' # 设置模型缓存目录
# 配置模型缓存目录(不设置离线模式,让它自动选择)
# 如果本地有模型就用本地的,没有才联网下载
if 'SENTENCE_TRANSFORMERS_HOME' not in os.environ:
os.environ['SENTENCE_TRANSFORMERS_HOME'] = 'embedding'
class MemoryService:
@@ -46,33 +45,75 @@ class MemoryService:
logger.info("🔄 正在加载Embedding模型...")
# 确保模型缓存目录存在
model_cache_dir = 'data/models'
model_cache_dir = 'embedding'
os.makedirs(model_cache_dir, exist_ok=True)
# 调试信息:打印环境变量和路径
logger.info(f"📂 当前工作目录: {os.getcwd()}")
logger.info(f"📂 模型缓存目录: {os.path.abspath(model_cache_dir)}")
logger.info(f"🔧 SENTENCE_TRANSFORMERS_HOME: {os.environ.get('SENTENCE_TRANSFORMERS_HOME', '未设置')}")
logger.info(f"🔧 TRANSFORMERS_OFFLINE: {os.environ.get('TRANSFORMERS_OFFLINE', '未设置')}")
logger.info(f"🔧 HF_HUB_OFFLINE: {os.environ.get('HF_HUB_OFFLINE', '未设置')}")
# 检查模型目录内容
if os.path.exists(model_cache_dir):
logger.info(f"📁 模型目录存在,检查内容...")
try:
items = os.listdir(model_cache_dir)
logger.info(f"📁 模型目录内容: {items}")
# 检查是否有预期的模型文件夹
expected_model_dir = os.path.join(model_cache_dir, 'models--sentence-transformers--paraphrase-multilingual-MiniLM-L12-v2')
if os.path.exists(expected_model_dir):
logger.info(f"✅ 找到本地模型目录: {expected_model_dir}")
# 检查快照目录
snapshots_dir = os.path.join(expected_model_dir, 'snapshots')
if os.path.exists(snapshots_dir):
snapshots = os.listdir(snapshots_dir)
logger.info(f"📁 模型快照: {snapshots}")
else:
logger.warning(f"⚠️ 未找到本地模型目录: {expected_model_dir}")
except Exception as e:
logger.error(f"❌ 检查模型目录失败: {str(e)}")
else:
logger.warning(f"⚠️ 模型目录不存在: {os.path.abspath(model_cache_dir)}")
try:
logger.info("🔄 尝试加载主模型: sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
# 优先使用本地缓存的模型
# cache_folder会让模型优先从本地加载,只有不存在时才联网下载
# 注意:不要设置local_files_only=True,这会阻止fallback到联网下载
self.embedding_model = SentenceTransformer(
'paraphrase-multilingual-MiniLM-L12-v2',
'sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2',
cache_folder=model_cache_dir,
device='cpu' # 明确指定使用CPU
device='cpu', # 明确指定使用CPU
trust_remote_code=False # 安全起见
)
logger.info("✅ Embedding模型加载成功")
logger.info("✅ Embedding模型加载成功 (paraphrase-multilingual-MiniLM-L12-v2)")
except Exception as e:
logger.warning(f"⚠️ 无法加载多语言模型: {str(e)}")
logger.info("🔄 尝试使用备用模型...")
logger.error(f"❌ 详细错误: {repr(e)}")
import traceback
logger.error(f"❌ 错误堆栈:\n{traceback.format_exc()}")
logger.info("🔄 尝试使用备用模型: sentence-transformers/all-MiniLM-L6-v2")
try:
# 降级到更小的模型作为备选
self.embedding_model = SentenceTransformer(
'all-MiniLM-L6-v2',
'sentence-transformers/all-MiniLM-L6-v2',
cache_folder=model_cache_dir,
device='cpu'
device='cpu',
trust_remote_code=False
)
logger.info("✅ 使用备用Embedding模型")
logger.info("✅ 使用备用Embedding模型 (all-MiniLM-L6-v2)")
except Exception as e2:
logger.error(f"❌ 所有模型加载失败: {str(e2)}")
logger.error(f"❌ 详细错误: {repr(e2)}")
import traceback
logger.error(f"❌ 错误堆栈:\n{traceback.format_exc()}")
logger.error("💡 模型首次使用需要联网下载(约420MB)")
logger.error(" 或手动下载模型文件到 data/models 目录")
logger.error(" 或手动下载模型文件到 embedding 目录")
logger.error(f"💡 期望的模型目录结构:")
logger.error(f" {os.path.abspath(model_cache_dir)}/models--sentence-transformers--paraphrase-multilingual-MiniLM-L12-v2/")
raise RuntimeError("无法加载任何Embedding模型")
self._initialized = True