diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..90e7e65
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..b14c225
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..3a65488
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/py.iml b/.idea/py.iml
new file mode 100644
index 0000000..5a0e028
--- /dev/null
+++ b/.idea/py.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 2169bb7..4e60cd4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -20,6 +20,6 @@ RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com
COPY predict_with_excel.py .
COPY degree3/ ./degree3/
-EXPOSE 8000
+EXPOSE 8001
-CMD ["uvicorn", "predict_with_excel:app", "--host", "0.0.0.0", "--port", "8000"]
\ No newline at end of file
+CMD ["uvicorn", "predict_with_excel:app", "--host", "0.0.0.0", "--port", "8001"]
\ No newline at end of file
diff --git a/README.md b/README.md
deleted file mode 100644
index 8b82a18..0000000
--- a/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# gc_worktime
-
diff --git a/direct_test.py b/direct_test.py
new file mode 100644
index 0000000..549a586
--- /dev/null
+++ b/direct_test.py
@@ -0,0 +1,51 @@
+import pandas as pd
+import numpy as np
+from pathlib import Path
+import joblib
+
+# 直接测试模型加载功能
+print("=== Direct Model Loading Test ===")
+
+# 设置模型文件夹路径
+model_folder = Path("./degree3")
+print(f"Model folder path: {model_folder}")
+print(f"Model folder exists: {model_folder.exists()}")
+
+# 加载EV17.5相关的模型
+try:
+ # 加载EV17.5_立焊模型
+ ev175_vertical_model_path = model_folder / "EV17.5_立焊.xlsx_model_degree3.pkl"
+ print(f"EV17.5_立焊 model path: {ev175_vertical_model_path}")
+ print(f"EV17.5_立焊 model exists: {ev175_vertical_model_path.exists()}")
+
+ if ev175_vertical_model_path.exists():
+ ev175_vertical_model = joblib.load(ev175_vertical_model_path)
+ print(f"EV17.5_立焊 model loaded successfully!")
+
+ # 测试模型预测
+ test_thickness = np.array([[9.0]])
+ prediction = ev175_vertical_model.predict(test_thickness)
+ print(f"EV17.5_立焊 prediction for thickness 9.0mm: {prediction}")
+ else:
+ print(f"EV17.5_立焊 model file not found!")
+
+ # 加载EV17.5_横焊模型
+ ev175_horizontal_model_path = model_folder / "EV17.5_横焊.xlsx_model_degree3.pkl"
+ print(f"\nEV17.5_横焊 model path: {ev175_horizontal_model_path}")
+ print(f"EV17.5_横焊 model exists: {ev175_horizontal_model_path.exists()}")
+
+ if ev175_horizontal_model_path.exists():
+ ev175_horizontal_model = joblib.load(ev175_horizontal_model_path)
+ print(f"EV17.5_横焊 model loaded successfully!")
+
+ # 测试模型预测
+ test_thickness = np.array([[9.0]])
+ prediction = ev175_horizontal_model.predict(test_thickness)
+ print(f"EV17.5_横焊 prediction for thickness 9.0mm: {prediction}")
+ else:
+ print(f"EV17.5_横焊 model file not found!")
+
+except Exception as e:
+ print(f"Error during model loading or prediction: {e}")
+ import traceback
+ traceback.print_exc()
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 585a0a4..61ff106 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -3,8 +3,9 @@
services:
welding-app:
build: .
+ container_name: welding-app
ports:
- - "8000:8000"
+ - "8001:8001"
# volumes:
# - ./degree3:/app/degree3
# - ./data:/app/data
diff --git a/predict_with_excel.py b/predict_with_excel.py
index 7c73cc8..de3c3e7 100644
--- a/predict_with_excel.py
+++ b/predict_with_excel.py
@@ -123,7 +123,8 @@ def split_by_plus(s: str) -> list[str]:
# %%
import joblib
-folder_path = Path("./degree3")
+# 使用绝对路径来确保模型文件能够被正确找到
+folder_path = Path(__file__).parent / "degree3"
def load_all_models():
@@ -131,14 +132,10 @@ def load_all_models():
加载所有模型到 model_list
"""
global model_list
- # 清空列表以确保重新加载(尽管有启动时加载一次的逻辑)
- # model_list = []
- # ^^^ 注释掉这行,因为 FastAPI 的 on_event("startup") 应该只执行一次。
- # 如果在开发中需要热重载模型,可以取消注释或提供专门的重载端点。
-
- if model_list: # 如果已经加载过,则不再重复加载 (主要由 startup_event 控制)
- print(f"[MODEL_LOADER] Models already loaded. Count: {len(model_list)}")
- return
+ # 清空列表以确保重新加载
+ model_list = []
+
+ print(f"[MODEL_LOADER] Attempting to load models...")
print(
f"[MODEL_LOADER] Attempting to load models. Initial model_list length: {len(model_list)}"
@@ -187,26 +184,15 @@ def load_all_models():
for file_path_obj in files_found:
if file_path_obj.is_file():
try:
- model_name_parts = file_path_obj.name.split(".xlsx")
- if len(model_name_parts) > 1:
- model_name = model_name_parts[0]
- else:
- model_name_base = file_path_obj.stem
- if model_name_base.endswith("_model_degree3"):
- model_name = model_name_base[: -len("_model_degree3")]
- elif model_name_base.endswith(
- "3"
- ): # 兼容 *3.pkl 但不含 .xlsx 的情况
- model_name = model_name_base[: -len("3")].rstrip(
- "."
- ) # 移除可能的尾部'.' (来自.pkl)
- if model_name.endswith("_model_degree"): # 进一步处理
- model_name = model_name[: -len("_model_degree")]
- else:
- model_name = model_name_base
- print(
- f"[MODEL_LOADER] WARNING: Filename {file_path_obj.name} does not contain '.xlsx' as expected for name splitting. Using '{model_name}' as model name based on stem."
- )
+ filename = file_path_obj.name
+ # 移除文件扩展名 .pkl
+ model_name = filename[:-4]
+ # 移除 _model_degree3 后缀
+ if model_name.endswith("_model_degree3"):
+ model_name = model_name[:-14]
+ # 移除 .xlsx 后缀(如果存在)
+ if ".xlsx" in model_name:
+ model_name = model_name.split(".xlsx")[0]
loaded_model = joblib.load(file_path_obj)
temp_model_list.append(
@@ -237,6 +223,12 @@ def load_all_models():
def get_welding_coefficient(row):
coefficient = 0.0
global model_list
+
+ # 添加调试日志,查看model_list的长度和内容
+ print(f"[DEBUG] model_list length: {len(model_list)}")
+ loaded_model_names = [model["name"] for model in model_list]
+ print(f"[DEBUG] Loaded models: {loaded_model_names}")
+
model_map = {model["name"]: model for model in model_list}
lenth = row.长度_m
welding_type = row.坡口代码
@@ -275,26 +267,33 @@ def get_welding_coefficient(row):
# 如果已经是系数形式,直接累加
coefficient += float(item.replace("min/m", "").strip())
else:
- model_name = f"{item}_{welding_position}"
- selected_model_info = model_map.get(model_name)
- if selected_model_info is None:
- raise KeyError(f"模型 '{model_name}' 未加载")
- model = selected_model_info["model"]
- range_str = MODEL_RANGES.get(model_name, "0-Infinity")
- min_val_str, max_val_str = range_str.split("-")
- min_val = float(min_val_str)
- max_val = None if max_val_str == "Infinity" else float(max_val_str)
- if thickness_value < min_val or (
- max_val is not None and thickness_value > max_val
- ):
- print(
- f"⚠️ 警告: 厚度 {thickness_value}mm 超出模型 '{model_name}' 的适用范围 ({range_str} mm)。"
- )
- coefficient = float('nan')
- break
- else:
- prediction = float(model.predict(thickness_array)[0])
- coefficient += prediction
+ model_name = f"{item}_{welding_position}"
+ selected_model_info = model_map.get(model_name)
+ if selected_model_info is None:
+ print(f"⚠️ 处理坡口代码模型不存在: {model_name}, 错误: 模型未加载")
+ coefficient = float('nan')
+ break
+ model = selected_model_info["model"]
+ range_str = MODEL_RANGES.get(model_name, "0-Infinity")
+ min_val_str, max_val_str = range_str.split("-")
+ min_val = float(min_val_str)
+ max_val = None if max_val_str == "Infinity" else float(max_val_str)
+ if thickness_value < min_val or (
+ max_val is not None and thickness_value > max_val
+ ):
+ print(
+ f"⚠️ 警告: 厚度 {thickness_value}mm 超出模型 '{model_name}' 的适用范围 ({range_str} mm)。"
+ )
+ coefficient = float('nan')
+ break
+ else:
+ try:
+ prediction = float(model.predict(thickness_array)[0])
+ coefficient += prediction
+ except Exception as e:
+ print(f"⚠️ 模型预测失败: {model_name}, 错误: {e}")
+ coefficient = float('nan')
+ break
except Exception as e:
coefficient = float('nan')
print(
@@ -391,6 +390,9 @@ def process_excel(
当 sheet_name 为 None 时,处理工作簿内所有工作表并返回 {sheet_name: DataFrame}。
"""
+
+ # 在每次预测之前重新加载模型,确保模型能够被正确加载
+ load_all_models()
path_like, excel_bytes = _prepare_excel_source(excel_source)
@@ -426,6 +428,21 @@ def startup_event():
load_all_models()
+@app.get("/models", summary="获取已加载的模型列表")
+def get_models():
+ """
+ 获取已加载的模型列表,用于调试和检查模型加载状态
+ """
+ global model_list
+ return {
+ "total_models": len(model_list),
+ "models": [{
+ "name": model["name"],
+ "filename": model["filename"]
+ } for model in model_list]
+ }
+
+
def _sanitize_sheet_name(name: Union[str, int], existing: set[str]) -> str:
base = str(name) if str(name).strip() else "Sheet"
base = base[:31]
@@ -520,7 +537,36 @@ async def predict(
def main():
+ print("[TEST] Script started...")
+
+ # 检查degree3文件夹是否存在
+ print(f"[TEST] Current file path: {__file__}")
+ print(f"[TEST] Folder path: {folder_path}")
+ print(f"[TEST] Folder exists: {folder_path.exists()}")
+ print(f"[TEST] Folder is directory: {folder_path.is_dir()}")
+
+ # 列出degree3文件夹中的文件
+ if folder_path.exists() and folder_path.is_dir():
+ files = list(folder_path.glob("*3.pkl"))
+ print(f"[TEST] Number of model files found: {len(files)}")
+ for file in files[:10]: # 显示前10个文件
+ print(f"[TEST] Found model file: {file.name}")
+
+ # 加载模型
load_all_models()
+
+ # 添加调试信息,显示加载的模型名称
+ print(f"[DEBUG] Total models loaded: {len(model_list)}")
+ for model in model_list:
+ print(f"[DEBUG] Loaded model: {model['name']} from {model['filename']}")
+
+ # 检查是否包含CV17.5相关的模型
+ cv175_models = [model['name'] for model in model_list if 'CV17.5' in model['name']]
+ print(f"[DEBUG] CV17.5 models found: {cv175_models}")
+
+ # 检查是否包含平焊相关的模型
+ pinghan_models = [model['name'] for model in model_list if '平焊' in model['name']]
+ print(f"[DEBUG] 平焊 models found: {pinghan_models}")
# result_obj = process_excel(source_excel_path, sheet_name=0)
# output_file_path = source_excel_path.parent.joinpath(
# source_excel_path.stem + "_预测结果.xlsx"
diff --git a/test_model_load.py b/test_model_load.py
new file mode 100644
index 0000000..fbb5128
--- /dev/null
+++ b/test_model_load.py
@@ -0,0 +1,34 @@
+import os
+import sys
+from pathlib import Path
+
+# 添加当前目录到Python路径
+sys.path.append(str(Path(__file__).parent))
+
+# 导入需要的模块
+from predict_with_excel import load_all_models, model_list
+
+# 测试模型加载
+print("[TEST] Starting model loading test...")
+print(f"[TEST] Current working directory: {os.getcwd()}")
+
+# 加载模型
+load_all_models()
+
+# 显示加载的模型信息
+print(f"[TEST] Total models loaded: {len(model_list)}")
+if model_list:
+ print("[TEST] Loaded models:")
+ for model in model_list:
+ print(f" - {model['name']}")
+else:
+ print("[TEST] No models were loaded!")
+
+# 检查EV17.5相关的模型
+ev175_models = [model for model in model_list if 'EV17.5' in model['name']]
+print(f"[TEST] EV17.5 models found: {len(ev175_models)}")
+if ev175_models:
+ for model in ev175_models:
+ print(f" - {model['name']}")
+else:
+ print("[TEST] No EV17.5 models found!")
\ No newline at end of file