fix:1.修复模型文件被覆盖问题
This commit is contained in:
@@ -43,8 +43,6 @@ backend/data/*.db
|
|||||||
# ChromaDB数据库(不包含在镜像中,会在运行时生成)
|
# ChromaDB数据库(不包含在镜像中,会在运行时生成)
|
||||||
backend/data/chroma_db/
|
backend/data/chroma_db/
|
||||||
|
|
||||||
# 注意:backend/data/models/ 目录需要打包(包含预下载的Embedding模型)
|
|
||||||
# 所以不要添加到 .dockerignore 中
|
|
||||||
|
|
||||||
# 日志文件
|
# 日志文件
|
||||||
logs/
|
logs/
|
||||||
|
|||||||
+1
-2
@@ -102,8 +102,7 @@ dmypy.json
|
|||||||
# Jupyter Notebook
|
# Jupyter Notebook
|
||||||
.ipynb_checkpoints
|
.ipynb_checkpoints
|
||||||
|
|
||||||
data/*
|
data/
|
||||||
!/data/models/
|
|
||||||
docs/
|
docs/
|
||||||
data_old/
|
data_old/
|
||||||
backend/migrate_all_databases.py
|
backend/migrate_all_databases.py
|
||||||
|
|||||||
+4
-4
@@ -53,11 +53,11 @@ COPY backend/ ./
|
|||||||
COPY --from=frontend-builder /frontend/dist ./static
|
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的模型文件
|
# 这样可以避免首次运行时联网下载约420MB的模型文件
|
||||||
COPY backend/data/models /app/data/models
|
COPY backend/data/models /app/embedding
|
||||||
|
|
||||||
# 复制环境变量示例文件
|
# 复制环境变量示例文件
|
||||||
COPY backend/.env.example ./.env.example
|
COPY backend/.env.example ./.env.example
|
||||||
@@ -74,7 +74,7 @@ ENV APP_PORT=8000
|
|||||||
ENV TRANSFORMERS_OFFLINE=1
|
ENV TRANSFORMERS_OFFLINE=1
|
||||||
ENV HF_DATASETS_OFFLINE=1
|
ENV HF_DATASETS_OFFLINE=1
|
||||||
ENV HF_HUB_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 \
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||||
|
|||||||
@@ -10,11 +10,10 @@ import hashlib
|
|||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
# 配置离线模式,避免联网检查
|
# 配置模型缓存目录(不设置离线模式,让它自动选择)
|
||||||
os.environ['TRANSFORMERS_OFFLINE'] = '1'
|
# 如果本地有模型就用本地的,没有才联网下载
|
||||||
os.environ['HF_DATASETS_OFFLINE'] = '1'
|
if 'SENTENCE_TRANSFORMERS_HOME' not in os.environ:
|
||||||
os.environ['HF_HUB_OFFLINE'] = '1' # 禁用HuggingFace Hub联网
|
os.environ['SENTENCE_TRANSFORMERS_HOME'] = 'embedding'
|
||||||
os.environ['SENTENCE_TRANSFORMERS_HOME'] = 'data/models' # 设置模型缓存目录
|
|
||||||
|
|
||||||
|
|
||||||
class MemoryService:
|
class MemoryService:
|
||||||
@@ -46,33 +45,75 @@ class MemoryService:
|
|||||||
logger.info("🔄 正在加载Embedding模型...")
|
logger.info("🔄 正在加载Embedding模型...")
|
||||||
|
|
||||||
# 确保模型缓存目录存在
|
# 确保模型缓存目录存在
|
||||||
model_cache_dir = 'data/models'
|
model_cache_dir = 'embedding'
|
||||||
os.makedirs(model_cache_dir, exist_ok=True)
|
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:
|
try:
|
||||||
|
logger.info("🔄 尝试加载主模型: sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
|
||||||
# 优先使用本地缓存的模型
|
# 优先使用本地缓存的模型
|
||||||
# cache_folder会让模型优先从本地加载,只有不存在时才联网下载
|
# cache_folder会让模型优先从本地加载,只有不存在时才联网下载
|
||||||
|
# 注意:不要设置local_files_only=True,这会阻止fallback到联网下载
|
||||||
self.embedding_model = SentenceTransformer(
|
self.embedding_model = SentenceTransformer(
|
||||||
'paraphrase-multilingual-MiniLM-L12-v2',
|
'sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2',
|
||||||
cache_folder=model_cache_dir,
|
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:
|
except Exception as e:
|
||||||
logger.warning(f"⚠️ 无法加载多语言模型: {str(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:
|
try:
|
||||||
# 降级到更小的模型作为备选
|
# 降级到更小的模型作为备选
|
||||||
self.embedding_model = SentenceTransformer(
|
self.embedding_model = SentenceTransformer(
|
||||||
'all-MiniLM-L6-v2',
|
'sentence-transformers/all-MiniLM-L6-v2',
|
||||||
cache_folder=model_cache_dir,
|
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:
|
except Exception as e2:
|
||||||
logger.error(f"❌ 所有模型加载失败: {str(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("💡 模型首次使用需要联网下载(约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模型")
|
raise RuntimeError("无法加载任何Embedding模型")
|
||||||
|
|
||||||
self._initialized = True
|
self._initialized = True
|
||||||
|
|||||||
Reference in New Issue
Block a user