| |
| """ |
| 安装依赖并启动 PicExam API 的脚本 |
| 自动检测和安装缺失的依赖 |
| """ |
|
|
| import subprocess |
| import sys |
| import os |
| import importlib |
|
|
| def check_dependency(package_name, import_name=None): |
| """检查依赖是否已安装""" |
| if import_name is None: |
| import_name = package_name |
| |
| try: |
| importlib.import_module(import_name) |
| return True |
| except ImportError: |
| return False |
|
|
| def install_package(package_name): |
| """安装单个包""" |
| print(f"📦 安装 {package_name}...") |
| try: |
| subprocess.check_call([sys.executable, "-m", "pip", "install", package_name]) |
| print(f"✅ {package_name} 安装成功") |
| return True |
| except subprocess.CalledProcessError as e: |
| print(f"❌ {package_name} 安装失败: {e}") |
| return False |
|
|
| def check_and_install_dependencies(): |
| """检查并安装所有依赖""" |
| print("🔍 检查依赖...") |
| |
| |
| dependencies = [ |
| ("fastapi", "fastapi"), |
| ("uvicorn[standard]", "uvicorn"), |
| ("python-multipart", "multipart"), |
| ("torch", "torch"), |
| ("torchvision", "torchvision"), |
| ("transformers", "transformers"), |
| ("accelerate", "accelerate"), |
| ("qwen-vl-utils", "qwen_vl_utils"), |
| ("Pillow", "PIL"), |
| ("requests", "requests"), |
| ("numpy", "numpy"), |
| ("psutil", "psutil"), |
| ("av", "av"), |
| ("opencv-python-headless", "cv2"), |
| ("pydantic", "pydantic") |
| ] |
| |
| missing_packages = [] |
| |
| for pip_name, import_name in dependencies: |
| if not check_dependency(import_name): |
| missing_packages.append(pip_name) |
| print(f"❌ 缺失: {pip_name}") |
| else: |
| print(f"✅ 已安装: {pip_name}") |
| |
| if missing_packages: |
| print(f"\n📦 需要安装 {len(missing_packages)} 个包...") |
| |
| |
| try: |
| print("🚀 批量安装依赖...") |
| subprocess.check_call([ |
| sys.executable, "-m", "pip", "install" |
| ] + missing_packages) |
| print("✅ 所有依赖安装完成") |
| return True |
| except subprocess.CalledProcessError: |
| print("⚠️ 批量安装失败,尝试逐个安装...") |
| |
| |
| failed_packages = [] |
| for package in missing_packages: |
| if not install_package(package): |
| failed_packages.append(package) |
| |
| if failed_packages: |
| print(f"\n❌ 以下包安装失败: {', '.join(failed_packages)}") |
| print("💡 请手动安装:") |
| print(f" pip install {' '.join(failed_packages)}") |
| return False |
| else: |
| print("✅ 所有依赖安装完成") |
| return True |
| else: |
| print("✅ 所有依赖都已安装") |
| return True |
|
|
| def start_server(): |
| """启动服务器""" |
| print("\n🚀 启动 PicExam API 服务器...") |
| print("📝 注意: 首次启动会下载模型,可能需要较长时间") |
| print("🔗 服务器启动后可访问:") |
| print(" - 主页: http://localhost:7860/") |
| print(" - Web界面: http://localhost:7860/web") |
| print(" - API文档: http://localhost:7860/docs") |
| print(" - 依赖检查: http://localhost:7860/dependencies") |
| print("-" * 50) |
| |
| try: |
| |
| env = os.environ.copy() |
| env["PYTORCH_CUDA_ALLOC_CONF"] = "max_split_size_mb:512" |
| env["TOKENIZERS_PARALLELISM"] = "false" |
| env["OMP_NUM_THREADS"] = "4" |
| env["MKL_NUM_THREADS"] = "4" |
| |
| |
| subprocess.run([ |
| sys.executable, "-m", "uvicorn", |
| "app:app", |
| "--host", "0.0.0.0", |
| "--port", "7860", |
| "--reload", |
| "--timeout-keep-alive", "300" |
| ], env=env) |
| |
| except KeyboardInterrupt: |
| print("\n🛑 服务器已停止") |
| except Exception as e: |
| print(f"❌ 服务器启动失败: {e}") |
|
|
| def show_troubleshooting(): |
| """显示故障排除信息""" |
| print("\n🔧 故障排除:") |
| print("=" * 50) |
| print("1. 如果模型下载慢:") |
| print(" - 配置 HuggingFace 镜像源") |
| print(" - 使用代理或 VPN") |
| print() |
| print("2. 如果内存不足:") |
| print(" - 关闭其他程序释放内存") |
| print(" - 访问 /memory_status 检查内存使用") |
| print(" - 使用 /clear_cache 清理缓存") |
| print() |
| print("3. 如果依赖安装失败:") |
| print(" - 升级 pip: python -m pip install --upgrade pip") |
| print(" - 使用国内镜像: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/") |
| print() |
| print("4. 如果推理速度慢:") |
| print(" - 确保 CPU 有足够核心数") |
| print(" - 检查系统负载") |
| print() |
| print("5. 获取帮助:") |
| print(" - 访问 /dependencies 检查依赖状态") |
| print(" - 查看服务器日志") |
| print(" - 运行 python quick_test.py 进行诊断") |
|
|
| def main(): |
| """主函数""" |
| print("🤖 PicExam API 自动安装和启动器") |
| print("=" * 50) |
| print("📋 配置信息:") |
| print(" - 模型: Qwen2-VL-2B-Instruct") |
| print(" - 推理: CPU 模式") |
| print(" - 内存优化: 启用") |
| print(" - 端口: 7860") |
| print("=" * 50) |
| |
| |
| if not check_and_install_dependencies(): |
| print("\n❌ 依赖安装失败,无法启动服务") |
| show_troubleshooting() |
| return |
| |
| |
| show_troubleshooting() |
| |
| |
| try: |
| response = input("\n是否现在启动服务器? (Y/n): ").strip().lower() |
| if response in ['', 'y', 'yes']: |
| start_server() |
| else: |
| print("启动已取消") |
| print("💡 手动启动命令: uvicorn app:app --host 0.0.0.0 --port 7860") |
| except KeyboardInterrupt: |
| print("\n启动已取消") |
|
|
| if __name__ == "__main__": |
| main() |
|
|