Python与模型相关知识以及问题的整理之二

CoPilot用Claude Sonnet 4模型调试多平台自动安装python训练模型或机器学习环境

PHPer 2025-09-05 10 0 0

Sorry, your request failed. Please try again. Request id: ffd3eb9c-a6d7-45a5-9c90-f125436d026d

Claude Sonnet 4模型好像调用次数没了。报错Reason: Request Failed: 400 {"error":{"message":"messages.1.content.1.tool_use.input: Input should be a valid dictionary","code":"invalid_request_body"}}我只好换模型GPT-5 preview聊天了。20250905 0416

python -c "import torch; print(torch.__version__)"

Copilot用Claude Sonnet 4模型的阶段性总结。

总结

我已经完成了对您脚本的全面优化,解决了以下问题:

🔧 主要改进

超时处理增强

大型包(torch, torchaudio, torchvision)超时时间延长至30分钟

详细的超时日志记录,包含镜像、时间、包列表等信息

自动保存超时详情到日志文件

智能包检测

torch: 检测是否为GPU版本(包含+cu标识)

torchaudio/torchvision: 检查版本兼容性而不是强制要求GPU后缀

您当前的安装(torch 2.8.0+cu128, torchaudio 2.8.0, torchvision 0.23.0)会被正确识别为兼容并跳过重装

进度显示优化

每条下载信息显示已用时间...

立即注册
更新于:2025-09-05 04:26:05
    您需要登录后才可以评论。 立即注册

    文心一言调试多平台自动安装python训练模型或机器学习环境

    torch,torchvision,torchaudio 已经安装了。

    运行./setup_train_env.sh --core-packages torch,torchvision,torchaudio 还是是会下载安装torch ,"--core-packages torch,torchvision,torchaudio"CLI的含义是保护这些核心包不被重复安装或被其他安装的包依赖安装。终端输出的部分内容:Requirement already satisfied: mpmath<1.4,>=1.1.0 in g:\programdata\miniconda3_win11\lib\site-packages (from sympy>=1.13.3->torch) (1.3.0)

    Requirement already satisfied: MarkupSafe>=2.0 in g:\programdata\miniconda3_win11\lib\site-packages (from jinja2->torch) (3.0.2)

    📥 [9s] Downloading torch-2.8.0-cp313-cp313-win_amd64.whl (241.3 MB)

    ⏳ 正在下载大型 PyTorch 文件 (241.3 MB),请耐心等待...

    ⏳ 大型包下载中... (已等待 1 分钟,请继续等待或按 Ctrl+C 跳过此镜像)

    🚀 [75s] ---------------------------------------- 241.3/241.3 MB 2.8 MB/s eta 0:00:00

    📥 [76s] Downloading torchaudio-2.8.0-cp313-cp313-win_amd64.whl (2.5 MB)

    ⏳ 正在下载大型 PyTorch 文件 (2.5 MB),请耐心等待...

    🚀 [76s] ---------------------------------------- 2.5/2.5 MB 4.5 MB/s eta 0:00:00

    📥 [76s] Downloading torchvision-0.23.0-cp313-cp313-win_amd64.whl (1.6 MB)

    ⏳ 正在下载大型 PyTorch 文件 (1.6 MB),请耐心等待...

    🚀 [77s] ---------------------------------------- 1.6/1.6 MB 4.2 MB/s eta 0:00:00

    📦 [78s] Installing collected packages: torch, torchvision, torchaudio

    ⏳ 大型包下载中... (已等待 2 分钟,请继续等待或按 Ctrl+C 跳过此镜像)


    #!/bin/bash
    # 在原有脚本的core包检查逻辑后添加以下强制跳过代码
    # 修改确保核心包安装的函数
    ensure_core_package_installed() {
        local core_package="$1"
        shift
        local conflict_packages=("$@")
        # 强制跳过已安装的核心包
        if pip show "$core_package" &> /dev/null; then
            ok "✅ 强制跳过已安装的核心包: $core_package"
            return 0
        fi
        # 原有安装逻辑...
        # ...
    }
    # 在调用安装核心包前添加环境检查
    if [ -n "$VIRTUAL_ENV" ]; then
        info "🔍 检测到虚拟环境: $VIRTUAL_ENV"
        # 强制使用虚拟环境中的pip
        alias pip="python -m pip"
    fi
    # 执行核心包安装时添加额外检查
    install_essential_large_packages() {
        # 原有逻辑...
        # 在安装前强制检查包是否已安装
        for pkg in "${large_packages_needed[@]}"; do
            if pip show "$pkg" &> /dev/null; then
                ok "✅ 跳过已安装的包: $pkg"
                continue
            fi
            # 安装逻辑...
        done
    }
    

    操作建议

    1. 手动验证安装状态:
    bash

    # 在脚本执行前运行pip list | grep -E 'torch|torchvision|torchaudio'

    1. 强制使用指定版本(在脚本开头添加):

    bash

    # 添加环境变量定义export TORCH_VERSION="2.8.0+cu128"export TORCHVISION_VERSION="0.23.0"

    1. 修复脚本执行方式:

    bash

    # 修改后执行bash setup_train_env.sh --core-packages torch,torchvision,torchaudio --force-skip-installed

    关键修改说明

    1. 增强包检查逻辑:在ensure_core_package_installed函数开头添加对已安装包的强制跳过逻辑,确保即使后续逻辑异常也不会重复安装。
    2. 环境隔离加固:通过VIRTUAL_ENV检测确保在虚拟环境中使用正确的pip,避免系统环境干扰。
    3. 版本锁定:通过环境变量明确指定PyTorch相关包的版本和CUDA版本,避免自动检测导致的版本不匹配。

    修改后的脚本将优先跳过已安装的核心包,仅在确实需要时才执行安装,同时通过环境变量明确版本要求,避免因版本检测错误导致的重复下载。

    20250905 0443

    脚本代码

    #!/bin/bash
    set -o pipefail
    # 使用说明函数(中文),在脚本头部即可调用
    usage() {
        # 将帮助输出到终端(/dev/tty),避免被外部管道如 | tee 捕获到日志
        if [ -w /dev/tty ]; then
            cat > /dev/tty <<'USAGE'
    用法: bash setup_train_env.sh [选项] [包...]
    
    选项:
        -h, --help                     显示本帮助并退出
        -d, --debug                    启用调试模式(set -x),打印执行跟踪
        --core-packages PACKAGES       指定核心包列表(逗号分隔,默认: torch,torchvision,torchaudio)
    
    环境变量(可选):
        ENV_NAME          虚拟环境名(默认: train_ss)
        WORKSPACE         工作目录(默认: /mnt/workspace 或 Windows 下 D:/workspace)
        PLATFORM          平台检测覆盖,默认自动检测
        TORCH_INDEX       指定 PyTorch wheel 的 index-url
    
    说明:
        - 脚本内部会尽量把所有时间显示为中国上海时间。
        - 若希望同时在控制台显示并写入日志,推荐在运行脚本时使用外部管道:
            bash setup_train_env.sh 2>&1 | tee -a ./logs/setup_env_$(date +%Y%m%d_%H%M%S).log
            或者在 Windows (Git Bash) 下:
            bash setup_train_env.sh 2>&1 | tee -a D:/logs/setup_env_$(date +%Y%m%d_%H%M%S).log
    
    示例:
        # 启用调试并指定环境名
        bash setup_train_env.sh --debug ENV_NAME=myenv
    
        # 指定自定义核心包
        bash setup_train_env.sh --core-packages "tensorflow,keras"
        
        # 指定多个核心包
        bash setup_train_env.sh --core-packages "torch,torchvision,numpy"
    
        # 使用外部 tee 将输出同时写日志并显示
        bash setup_train_env.sh 2>&1 | tee -a ./logs/setup_env_$(date +%Y%m%d_%H%M%S).log
    USAGE
        else
            cat <<'USAGE'
    用法: bash setup_train_env.sh [选项] [包...]
    
    选项:
        -h, --help                     显示本帮助并退出
        -d, --debug                    启用调试模式(set -x),打印执行跟踪
        --core-packages PACKAGES       指定核心包列表(逗号分隔,默认: torch,torchvision,torchaudio)
    
    环境变量(可选):
        ENV_NAME          虚拟环境名(默认: train_ss)
        WORKSPACE         工作目录(默认: /mnt/workspace 或 Windows 下 D:/workspace)
        PLATFORM          平台检测覆盖,默认自动检测
        TORCH_INDEX       指定 PyTorch wheel 的 index-url
    
    说明:
        - 脚本内部会尽量把所有时间显示为中国上海时间。
        - 若希望同时在控制台显示并写入日志,推荐在运行脚本时使用外部管道:
            bash setup_train_env.sh 2>&1 | tee -a ./logs/setup_env_$(date +%Y%m%d_%H%M%S).log
            或者在 Windows (Git Bash) 下:
            bash setup_train_env.sh 2>&1 | tee -a D:/logs/setup_env_$(date +%Y%m%d_%H%M%S).log
    
    示例:
        # 启用调试并指定环境名
        bash setup_train_env.sh --debug ENV_NAME=myenv
    
        # 使用外部 tee 将输出同时写日志并显示
        bash setup_train_env.sh 2>&1 | tee -a ./logs/setup_env_$(date +%Y%m%d_%H%M%S).log
    USAGE
        fi
        exit 0
    }
    
    # 支持通过命令行参数开启 DEBUG:--debug 或 -d;同时支持 --help/-h 和 --core-packages
    CORE_PACKAGES_ARG=""
    
    for _arg in "$@"; do
            case "$_arg" in
                    --debug|-d)
                            export DEBUG=1
                            ;;
                    --help|-h)
                            usage
                            ;;
                    --core-packages)
                            CORE_PACKAGES_NEXT=true
                            ;;
                    --core-packages=*)
                            CORE_PACKAGES_ARG="${_arg#*=}"
                            ;;
                    *)
                            if [[ "$CORE_PACKAGES_NEXT" == "true" ]]; then
                                    CORE_PACKAGES_ARG="$_arg"
                                    CORE_PACKAGES_NEXT=""
                            fi
                            ;;
            esac
    done
    
    # ========================================
    # 🔍 CLI参数验证
    # ========================================
    
    # 检查 --core-packages 参数是否有值
    if [[ "$CORE_PACKAGES_NEXT" == "true" ]]; then
        echo "❌ 错误: --core-packages 参数缺少参数值" >&2
        echo "" >&2
        echo "💡 正确用法:" >&2
        echo "   ./setup_train_env.sh --core-packages torch,torchvision,torchaudio" >&2
        echo "   ./setup_train_env.sh --core-packages=\"torch,torchvision,torchaudio\"" >&2
        echo "" >&2
        echo "📋 示例核心包列表:" >&2
        echo "   • PyTorch生态: torch,torchvision,torchaudio" >&2
        echo "   • TensorFlow生态: tensorflow,keras" >&2
        echo "   • 混合方案: torch,tensorflow,numpy" >&2
        echo "" >&2
        echo "🔍 查看完整帮助: ./setup_train_env.sh --help" >&2
        exit 1
    fi
    
    # 如果指定了核心包参数,验证格式
    if [[ -n "$CORE_PACKAGES_ARG" ]]; then
        # 检查是否为空字符串
        if [[ "$CORE_PACKAGES_ARG" == "" ]]; then
            echo "❌ 错误: --core-packages 参数值不能为空" >&2
            echo "💡 请提供有效的包列表,例如: torch,torchvision,torchaudio" >&2
            exit 1
        fi
        
        # 基本格式验证(检查是否包含有效字符)
        if [[ ! "$CORE_PACKAGES_ARG" =~ ^[a-zA-Z0-9_,-]+$ ]]; then
            echo "❌ 错误: --core-packages 参数值包含无效字符" >&2
            echo "💡 只允许字母、数字、下划线、连字符和逗号" >&2
            echo "💡 当前值: '$CORE_PACKAGES_ARG'" >&2
            exit 1
        fi
        
        echo "✅ 核心包参数验证通过: $CORE_PACKAGES_ARG" >&2
    fi
    
    # ========================================
    # � 智能环境检测和命令兼容性处理
    # ========================================
    
    # 检测当前shell环境
    detect_shell_environment() {
        local env_result=""
        local platform=""
        
        # 检测平台和环境
        if [[ "${OSTYPE:-}" == "msys" ]] || [[ "${MSYSTEM:-}" =~ ^(MINGW|MSYS) ]]; then
            platform="windows"
            env_result="GIT_BASH"
            export DETECTED_PLATFORM="windows"
            export DETECTED_SHELL="git_bash"
            export COMMANDS_AVAILABLE=true
        elif [[ "${OS:-}" == "Windows_NT" ]] || command -v powershell.exe >/dev/null 2>&1; then
            platform="windows"
            env_result="WINDOWS_POWERSHELL"
            export DETECTED_PLATFORM="windows"
            export DETECTED_SHELL="powershell"
            export COMMANDS_AVAILABLE=false
        elif [[ "${OSTYPE:-}" == "linux"* ]]; then
            platform="linux"
            # Linux下检查关键命令是否可用
            local missing_commands=()
            for cmd in grep sed cut awk; do
                if ! command -v "$cmd" >/dev/null 2>&1; then
                    missing_commands+=("$cmd")
                fi
            done
            
            if [ ${#missing_commands[@]} -eq 0 ]; then
                env_result="LINUX_BASH"
                export COMMANDS_AVAILABLE=true
            else
                env_result="LINUX_MINIMAL"
                export COMMANDS_AVAILABLE=false
                export MISSING_COMMANDS=("${missing_commands[@]}")
            fi
            export DETECTED_PLATFORM="linux"
            export DETECTED_SHELL="bash"
        elif [[ "${OSTYPE:-}" == "darwin"* ]]; then
            platform="macos"
            env_result="MACOS_BASH"
            export DETECTED_PLATFORM="macos"
            export DETECTED_SHELL="bash"
            export COMMANDS_AVAILABLE=true
        else
            # 未知环境,通过命令可用性判断
            if command -v grep >/dev/null 2>&1 && command -v sed >/dev/null 2>&1 && command -v cut >/dev/null 2>&1; then
                env_result="UNIX_COMPATIBLE"
                export COMMANDS_AVAILABLE=true
            else
                env_result="LIMITED_SHELL"
                export COMMANDS_AVAILABLE=false
            fi
            export DETECTED_PLATFORM="unknown"
            export DETECTED_SHELL="unknown"
        fi
        
        echo "$env_result"
    }
    
    # 🔧 Linux系统自动安装缺失命令
    install_missing_commands_linux() {
        local missing_commands=("$@")
        
        echo "🔧 尝试自动安装缺失命令: ${missing_commands[*]}" >&2
        
        # 检测包管理器并安装
        if command -v apt-get >/dev/null 2>&1; then
            echo "📦 使用 apt-get 安装..." >&2
            sudo apt-get update >/dev/null 2>&1
            sudo apt-get install -y gawk sed grep coreutils >/dev/null 2>&1
        elif command -v yum >/dev/null 2>&1; then
            echo "📦 使用 yum 安装..." >&2
            sudo yum install -y gawk sed grep coreutils >/dev/null 2>&1
        elif command -v dnf >/dev/null 2>&1; then
            echo "📦 使用 dnf 安装..." >&2
            sudo dnf install -y gawk sed grep coreutils >/dev/null 2>&1
        elif command -v pacman >/dev/null 2>&1; then
            echo "📦 使用 pacman 安装..." >&2
            sudo pacman -S --noconfirm gawk sed grep coreutils >/dev/null 2>&1
        elif command -v apk >/dev/null 2>&1; then
            echo "📦 使用 apk 安装..." >&2
            sudo apk add gawk sed grep coreutils >/dev/null 2>&1
        elif command -v zypper >/dev/null 2>&1; then
            echo "📦 使用 zypper 安装..." >&2
            sudo zypper install -y gawk sed grep coreutils >/dev/null 2>&1
        else
            echo "❌ 无法识别包管理器,请手动安装: ${missing_commands[*]}" >&2
            echo "" >&2
            echo "💡 常见安装命令:" >&2
            echo "   Ubuntu/Debian: sudo apt-get install gawk sed grep coreutils" >&2
            echo "   CentOS/RHEL:   sudo yum install gawk sed grep coreutils" >&2
            echo "   Fedora:        sudo dnf install gawk sed grep coreutils" >&2
            echo "   Arch Linux:    sudo pacman -S gawk sed grep coreutils" >&2
            echo "   Alpine:        sudo apk add gawk sed grep coreutils" >&2
            return 1
        fi
        
        # 验证安装结果
        local still_missing=()
        for cmd in "${missing_commands[@]}"; do
            if ! command -v "$cmd" >/dev/null 2>&1; then
                still_missing+=("$cmd")
            fi
        done
        
        if [ ${#still_missing[@]} -eq 0 ]; then
            echo "✅ 所有命令安装成功" >&2
            return 0
        else
            echo "⚠️ 部分命令安装失败: ${still_missing[*]}" >&2
            return 1
        fi
    }
    
    # 智能命令调用:根据环境选择最佳实现
    smart_grep() {
        local pattern="$1"
        shift
        local args=("$@")
        
        if [ "${COMMANDS_AVAILABLE:-false}" = true ] && command -v grep >/dev/null 2>&1; then
            # 使用原生grep
            grep "$pattern" "${args[@]}"
        else
            # 使用纯bash实现
            pure_bash_grep "$pattern" "${args[@]}"
        fi
    }
    
    smart_cut() {
        local delimiter=""
        local field=""
        local input=""
        
        # 解析参数
        while [[ $# -gt 0 ]]; do
            case "$1" in
                -d) delimiter="$2"; shift 2 ;;
                -f) field="$2"; shift 2 ;;
                *) input="$1"; shift ;;
            esac
        done
        
        if [ "${COMMANDS_AVAILABLE:-false}" = true ] && command -v cut >/dev/null 2>&1; then
            # 使用原生cut
            if [ -n "$input" ]; then
                echo "$input" | cut -d"$delimiter" -f"$field"
            else
                cut -d"$delimiter" -f"$field"
            fi
        else
            # 使用纯bash实现
            pure_bash_cut -d "$delimiter" -f "$field" "$input"
        fi
    }
    
    smart_sed() {
        local expression="$1"
        shift
        
        if [ "${COMMANDS_AVAILABLE:-false}" = true ] && command -v sed >/dev/null 2>&1; then
            # 使用原生sed
            sed "$expression" "$@"
        else
            # 使用纯bash实现(简化版)
            pure_bash_sed "$expression" "$@"
        fi
    }
    
    # 纯bash实现的文本处理函数(备用)
    pure_bash_grep() {
        local pattern="$1"
        local file="$2"
        local line
        
        if [ -f "$file" ]; then
            while IFS= read -r line; do
                case "$line" in
                    *"$pattern"*) echo "$line" ;;
                esac
            done < "$file"
        else
            # 从stdin读取
            while IFS= read -r line; do
                case "$line" in
                    *"$pattern"*) echo "$line" ;;
                esac
            done
        fi
    }
    
    pure_bash_cut() {
        local options="$1"
        local input="$2"
        local delimiter=" "
        local field=1
        
        # 解析cut参数
        case "$options" in
            *-d*)
                delimiter="${options#*-d}"
                if [ -z "$delimiter" ]; then
                    delimiter=" "
                fi
                ;;
            *-f*)
                field="${options#*-f}"
                ;;
        esac
        
        # 处理输入
        if [ -n "$input" ]; then
            echo "$input" | while IFS="$delimiter" read -ra parts; do
                if [ ${#parts[@]} -ge "$field" ]; then
                    echo "${parts[$((field-1))]}"
                fi
            done
        else
            while IFS="$delimiter" read -ra parts; do
                if [ ${#parts[@]} -ge "$field" ]; then
                    echo "${parts[$((field-1))]}"
                fi
            done
        fi
    }
    
    # 环境检测和初始化
    SHELL_ENV=$(detect_shell_environment)
    
    case "$SHELL_ENV" in
        "WINDOWS_POWERSHELL")
            echo "⚠️ 检测到 Windows PowerShell 环境" >&2
            echo "💡 建议使用 Git Bash 运行此脚本以获得最佳体验:" >&2
            echo "   1. 安装 Git for Windows (如果未安装): https://git-scm.com/download/win" >&2
            echo "   2. 右键点击文件夹,选择 'Git Bash Here'" >&2
            echo "   3. 运行命令:./setup_train_env.sh" >&2
            echo "" >&2
            echo "🔧 当前环境的限制:" >&2
            echo "   • 缺少 grep, sed, cut 等命令" >&2
            echo "   • 某些功能可能较慢或不可用" >&2
            echo "" >&2
            read -p "❓ 是否继续在当前环境中运行?(y/N): " continue_powershell
            if [[ ! "$continue_powershell" =~ ^[Yy]$ ]]; then
                echo "🔄 请在 Git Bash 中运行脚本以获得最佳体验" >&2
                exit 1
            fi
            echo "🔧 启用兼容模式继续运行..." >&2
            ;;
        "LINUX_MINIMAL")
            echo "⚠️ 检测到精简 Linux 环境,缺少必要命令" >&2
            echo "💡 缺失命令: ${MISSING_COMMANDS[*]}" >&2
            echo "" >&2
            echo "🔧 自动安装选项:" >&2
            read -p "❓ 是否尝试自动安装缺失命令?(y/N): " install_missing
            if [[ "$install_missing" =~ ^[Yy]$ ]]; then
                if install_missing_commands_linux "${MISSING_COMMANDS[@]}"; then
                    echo "✅ 命令安装成功,重新检测环境..." >&2
                    SHELL_ENV=$(detect_shell_environment)
                    if [ "$COMMANDS_AVAILABLE" = true ]; then
                        echo "✅ 环境准备完成" >&2
                    else
                        echo "⚠️ 某些命令可能未正确安装,使用兼容模式" >&2
                    fi
                else
                    echo "❌ 自动安装失败,使用兼容模式" >&2
                fi
            else
                echo "🔧 使用内置兼容模式继续运行..." >&2
            fi
            ;;
        "LIMITED_SHELL")
            echo "⚠️ 检测到受限shell环境" >&2
            echo "💡 建议在支持标准命令的环境中运行此脚本" >&2
            echo "" >&2
            read -p "❓ 是否继续在当前环境中运行?(y/N): " continue_limited
            if [[ ! "$continue_limited" =~ ^[Yy]$ ]]; then
                echo "🔄 请在支持的环境中运行脚本" >&2
                exit 1
            fi
            echo "🔧 使用兼容模式继续运行..." >&2
            ;;
        "GIT_BASH")
            echo "✅ Git Bash 环境检测成功,使用完整功能" >&2
            ;;
        "LINUX_BASH"|"MACOS_BASH"|"UNIX_COMPATIBLE")
            echo "✅ Unix 兼容环境检测成功,使用完整功能" >&2
            ;;
        *)
            echo "ℹ️ 未知shell环境,尝试自动适配" >&2
            ;;
    esac
    
    # ========================================
    # 🛠️  全局变量(可从外部传入或默认)
    # ========================================
    
    # 开启调试跟踪(set -x)仅在显式需要时打开,避免把执行跟踪写入控制台/日志
    # 可通过环境变量或命令行参数启用,如: DEBUG=1 bash setup_train_env.sh  或  bash setup_train_env.sh --debug
    if [[ "${DEBUG:-0}" -eq 1 ]]; then
        set -x
    fi
    
    # 确保终端环境正常
    export TERM="${TERM:-xterm-256color}"
    export PYTHONIOENCODING=utf-8
    
    # ========================================
    # 🕒 脚本开始:记录开始时间
    # ========================================
    # 使用中国上海时区时间(兼容不同环境)
    export TZ='Asia/Shanghai'
    # sh_date: 使用 TZ=Asia/Shanghai 调用 date,保证在不同平台下输出为上海时间
    sh_date() {
        # 优先使用系统时区数据(如果存在)
        if [ -r "/usr/share/zoneinfo/Asia/Shanghai" ]; then
            TZ='Asia/Shanghai' date "$@"
            return
        fi
    
        # 回退:如果系统缺少 zoneinfo,尝试使用 python/python3 将 UTC 时间 +8h 来格式化
        local args=("$@")
        local fmt=""
        local epoch=""
        local i
        for ((i=0;i<${#args[@]};i++)); do
            case "${args[i]}" in
                -d)
                    # 支持 -d @EPOCH 或 -d @ EPOCH 两种形式
                    if [ $((i+1)) -lt ${#args[@]} ]; then
                        val="${args[i+1]}"
                        if [ "${val}" = "@" ] && [ $((i+2)) -lt ${#args[@]} ]; then
                            epoch="@${args[i+2]}"
                            i=$((i+2))
                        else
                            epoch="${val}"
                            i=$((i+1))
                        fi
                    fi
                    ;;
                @*)
                    epoch="${args[i]}"
                    ;;
                +*)
                    fmt="${args[i]}"
                    ;;
                *)
                    ;;
            esac
        done
    
        if [ -z "$fmt" ]; then
            fmt='+%Y-%m-%d %H:%M:%S'
        fi
        local pyfmt="${fmt#+}"
    
        # 选择 python 可执行文件
        local pycmd=python
        if ! command -v "$pycmd" >/dev/null 2>&1; then
            pycmd=python3
        fi
        if ! command -v "$pycmd" >/dev/null 2>&1; then
        # 无 python 可用,回退到系统 date(使用 sh_date 回退到上海时间或尽力保持一致)
        sh_date "$@"
            return
        fi
    
        if [ -n "$epoch" ]; then
            epoch="${epoch#@}"
            if [ -z "$epoch" ]; then
                # epoch 为空,回退到 sh_date(避免 python int('') 错误)
                sh_date "$@"
                return
            fi
            "$pycmd" - "$pyfmt" "$epoch" <<'PY'
    import sys,datetime
    try:
        fmt = sys.argv[1]
        epoch = int(sys.argv[2])
        # 使用时区感知的 UTC 时间并转换为上海时区(UTC+8)
        dt = datetime.datetime.fromtimestamp(epoch, datetime.timezone.utc).astimezone(datetime.timezone(datetime.timedelta(hours=8)))
        print(dt.strftime(fmt))
    except Exception:
        pass
    PY
        else
            "$pycmd" - "$pyfmt" <<'PY'
    import sys,datetime
    try:
        fmt = sys.argv[1]
        dt = datetime.datetime.now(datetime.timezone.utc).astimezone(datetime.timezone(datetime.timedelta(hours=8)))
        print(dt.strftime(fmt))
    except Exception:
        pass
    PY
        fi
    }
    
    # 记录脚本开始时间(epoch)
    START_TIME=$(sh_date +%s)
    
    # 在函数顶部添加:
    local extra_index_url=""
    local trusted_hosts=()
    
    # 在参数解析循环中:
    for arg in "$@"; do
        if [[ "$arg" == --index-url ]]; then
            index_url_next=true
        elif [[ "$arg" == --extra-index-url ]]; then
            extra_index_url_next=true
        elif [[ "$arg" == --trusted-host ]]; then
            trusted_host_next=true
        elif $index_url_next; then
            index_url="$arg"
            index_url_next=false
        elif $extra_index_url_next; then
            extra_index_url="$arg"
            extra_index_url_next=false
        elif $trusted_host_next; then
            trusted_hosts+=("$arg")
            trusted_host_next=false
        elif [[ "$arg" == --* ]]; then
            extra_args+=("$arg")
        else
            packages+=("$arg")
        fi
    done
    
    # ========================================
    # 🛠️  全局变量(可从外部传入或默认)
    # ========================================    
    ENV_NAME="${ENV_NAME:-train_ss}"         # 虚拟环境名称
    WORKSPACE="${WORKSPACE:-/mnt/workspace}" # 工作空间根目录(可外部传入)
    
    # --- 修改 2: PLATFORM 优先外部传入 ---
    PLATFORM="${PLATFORM:-auto}"             # 平台类型   
    if [[ "$PLATFORM" == "auto" ]]; then
        PLATFORM=$(detect_platform)
    fi
    
    # ========================================
    # 🛠️  跨平台虚拟环境检测函数
    # ========================================
    check_virtual_env_support() {
        local has_venv=false
        local has_virtualenv=false
        local has_conda=false
        local python_cmd=""
        
        echo "🔍 检测虚拟环境支持..."
        
        # 1. 检测 Python 命令
        if command -v python3 >/dev/null 2>&1; then
            python_cmd="python3"
        elif command -v python >/dev/null 2>&1; then
            python_cmd="python"
        fi
        
        if [ -z "$python_cmd" ]; then
            echo "❌ 未检测到 Python"
            return 1
        fi
        
        echo "✅ 检测到 Python: $python_cmd ($($python_cmd --version 2>&1))"
        
        # 2. 检测 venv 模块(Python 3.3+ 内置)
        if $python_cmd -m venv --help >/dev/null 2>&1; then
            has_venv=true
            echo "✅ 支持 venv 模块"
        else
            echo "❌ 不支持 venv 模块"
        fi
        
        # 3. 检测 virtualenv(第三方包)
        if command -v virtualenv >/dev/null 2>&1; then
            has_virtualenv=true
            echo "✅ 支持 virtualenv: $(virtualenv --version 2>&1)"
        elif $python_cmd -m virtualenv --help >/dev/null 2>&1; then
            has_virtualenv=true
            echo "✅ 支持 virtualenv (通过 python -m)"
        else
            echo "❌ 不支持 virtualenv"
        fi
        
        # 4. 检测 conda
        if command -v conda >/dev/null 2>&1; then
            has_conda=true
            echo "✅ 支持 conda: $(conda --version 2>&1)"
        else
            echo "❌ 不支持 conda"
        fi
        
        # 5. 总结
        echo ""
        echo "📋 虚拟环境支持总结:"
        if $has_conda; then
            echo "  🐍 Conda: 可用 (推荐)"
        fi
        if $has_venv; then
            echo "  📦 venv: 可用 (Python 内置)"
        fi
        if $has_virtualenv; then
            echo "  🔧 virtualenv: 可用 (第三方)"
        fi
        
        if ! $has_venv && ! $has_virtualenv && ! $has_conda; then
            echo "  ❌ 无可用的虚拟环境工具"
            echo ""
            echo "💡 建议安装方法:"
            if [[ "$OSTYPE" == "linux-gnu"* ]]; then
                echo "  Ubuntu/Debian: sudo apt update && sudo apt install python3-venv"
                echo "  CentOS/RHEL: sudo yum install python3-venv 或 sudo dnf install python3-venv"
            elif [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]]; then
                echo "  Windows: pip install virtualenv 或安装 Anaconda/Miniconda"
            fi
            echo "  通用方法: pip install virtualenv"
            return 1
        fi
        
        return 0
    }
    
    # ========================================
    # 🛠️  封装函数:get_activate_cmd 获取环境激活cmd命令
    # ========================================
    get_activate_cmd() {
        local ENV_NAME="${1:-train_ss}"
        local VENV_PATH="${2:-/mnt/workspace/envs/${ENV_NAME}}"
    
        local ACTIVATE_CMD=""
        local ENV_TYPE=""
        local OS_TYPE="linux"
    
        # 1. 判断操作系统
        if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "win32" ]]; then
            OS_TYPE="windows"
        elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
            OS_TYPE="linux"
        else
            OS_TYPE="linux"
        fi
        echo "🔍 检测到操作系统: $OS_TYPE"
    
        # 2. 判断环境类型
        if command -v conda &> /dev/null; then
            if conda env list 2>/dev/null | smart_grep -q "^\s*${ENV_NAME}\s*" ; then
                ENV_TYPE="conda"
                echo "📦 检测到 Conda 环境: ${ENV_NAME}"
            fi
        fi
    
        if [[ -z "$ENV_TYPE" ]] && [ -f "${VENV_PATH}/bin/activate" ]; then
            ENV_TYPE="venv"
            echo "📦 检测到 venv 环境: ${VENV_PATH}"
        fi
    
        if [[ -z "$ENV_TYPE" ]]; then
            echo "❌ 错误:未找到环境 '${ENV_NAME}',既不是 conda 也不是 venv。"
            export ACTIVATE_CMD="NOT_FOUND"
            export DETECTED_ENV_TYPE="unknown"
            return 1
        fi
    
        # 3. 生成激活命令
        case "${ENV_TYPE}_${OS_TYPE}" in
            "conda_linux"|"conda_windows")
                if conda --version &> /dev/null; then
                    local CONDA_VERSION=$(conda --version | smart_extract_field 2)
                    if version_compare "4.4" "$CONDA_VERSION"; then
                        ACTIVATE_CMD="conda activate ${ENV_NAME}"
                    else
                        ACTIVATE_CMD="source activate ${ENV_NAME}"
                    fi
                else
                    ACTIVATE_CMD="source activate ${ENV_NAME}"
                fi
                ;;
    
            "venv_linux")
                ACTIVATE_CMD="source ${VENV_PATH}/bin/activate"
                ;;
    
            "venv_windows")
                ACTIVATE_CMD="${VENV_PATH}\\Scripts\\activate.bat"
                ;;
    
            *)
                ACTIVATE_CMD="UNKNOWN"
                ;;
        esac
    
        # 导出变量供外部使用
        export ACTIVATE_CMD
        export DETECTED_ENV_TYPE="$ENV_TYPE"
        echo "✅ ACTIVATE_CMD: ${ACTIVATE_CMD}"
    }
    
    
    # ========================================
    # 🛠️  定义 log_success 函数
    # ========================================
    log_success() {
        local PLATFORM="$1"
        local ENV_NAME="$2"
        local LOG_FILE_PATH="$3"
        local WORKSPACE="$4"
        local ACTIVATE_CMD="$5"
        local DETECTED_ENV_TYPE="$6"
    
        # 获取 GPU 信息
        local GPU_INFO
        GPU_INFO=$(python -c '
    import torch
    if torch.cuda.is_available():
        print(f"✅ {torch.cuda.get_device_name(0)} (CUDA {torch.version.cuda})")
    else:
        print("❌ 未启用")
    ' 2>/dev/null) || GPU_INFO="❌ 导入 PyTorch 失败"
    
        local CURRENT_TIME=$(sh_date '+%Y-%m-%d %H:%M:%S %Z')
        local END_TIME=$(sh_date +%s)
        local ELAPSED_TIME=$((END_TIME - START_TIME))
        local DURATION="$((ELAPSED_TIME / 60))m$((ELAPSED_TIME % 60))s"
    
        # 💡 1. 输出到终端(彩色,仅 stderr)
        {
        echo
        echo -e "✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨"
        echo -e "🎉 \033[1;33m环境配置成功!All Set!\033[0m 🎉"
        echo
        echo -e "📍 平台: \033[1;36m$PLATFORM\033[0m"
        echo -e "📍 环境: \033[1;32m$ENV_NAME\033[0m"
        echo -e "📍 环境类型: \033[1;35m${DETECTED_ENV_TYPE^}\033[0m"  # 首字母大写
        echo -e "📍 日志: \033[3;37m$LOG_FILE\033[0m"
        echo
        echo -e "💡 激活命令: \033[1;33m$ACTIVATE_CMD\033[0m"  # ✅ 使用动态命令
        echo -e "💡 GPU 支持: \033[1;32m$GPU_INFO\033[0m"
        echo
        echo -e "✅ 当前环境已就绪,可直接运行训练脚本。"
        echo -e "🕒 完成时间: $CURRENT_TIME"
        echo -e "⏱️  执行耗时: $DURATION (开始: $(sh_date -d "@${START_TIME}" '+%H:%M:%S'))"
        echo -e ""
        echo -e "支持的 CLI 参数(可直接用于命令行)"
        echo -e "--help, -h  说明:显示中文帮助(直接输出到终端,不写入日志),随后脚本退出。"
        echo -e "用法示例:bash setup_train_env.sh --help  或./setup_train_env.sh --help"
        echo -e "--debug, -d  说明:启用调试模式(等同于设置 DEBUG=1),脚本会执行 set -x 输出命令跟踪(用于排查)。"
        echo -e "用法示例:bash setup_train_env.sh --debug 或./setup_train_env.sh --debug "
        echo -e "✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨ ✨"
        echo
        } >&2
    
        # 📄 2. 写入日志(纯文本,结构化)
        {
        echo "----------------------------------------"
        echo "✅ ENV_SETUP_SUCCESS"
        echo "PLATFORM: $PLATFORM"
        echo "ENV_NAME: $ENV_NAME"
        echo "ENV_TYPE: $DETECTED_ENV_TYPE"
        echo "LOG_FILE: $LOG_FILE"
        echo "ACTIVATE_CMD: $ACTIVATE_CMD"
        echo "GPU_INFO: $GPU_INFO"
        echo "START_TIME: $(sh_date -d "@${START_TIME}" '+%Y-%m-%d %H:%M:%S')"
        echo "COMPLETION_TIME: $CURRENT_TIME"
        echo "ELAPSED_SECONDS: $ELAPSED_TIME"
        echo "EXECUTION_DURATION: $DURATION"
        echo "STATUS: OK"
        echo "----------------------------------------"
        } >> "$LOG_FILE" 2>&1
    }
    
    
    # 函数:记录带时间戳的日志
    log() {
        echo "[$(sh_date '+%Y-%m-%d %H:%M:%S %Z')] $1" | tee -a "$LOG_FILE"
    }
    
    
    
    # 错误处理函数
    on_error() {
        local exit_code=$?
        cat >&2 << EOF
    
    💥 脚本执行失败!
       行号: $1
       命令: $2
       退出码: $exit_code
       日志: ${LOG_FILE:-未定义}
    
    🔧 建议:
       - 检查 conda 是否可用: conda --version
       - 检查 D:/logs 是否可写
       - 手动运行失败命令
    
    EOF
        exit "$exit_code"
    }
    trap 'on_error $LINENO "$BASH_COMMAND"' ERR
    
    # 工具函数
    info()  { echo "ℹ️  $1"; }
    warn()  { echo "⚠️  $1"; }
    
    # 增强的错误函数:自动输出详细错误信息并保存到日志
    error() {
        local error_msg="$*"
        local error_time=$(sh_date '+%Y-%m-%d %H:%M:%S %Z')
        local error_details=""
        
        # 构建详细错误信息
        error_details="
    ====================================
    ❌ 错误发生时间: $error_time
    ❌ 错误信息: $error_msg
    ❌ 错误位置: ${BASH_SOURCE[1]:-未知}:${BASH_LINENO[0]:-未知}
    ❌ 当前工作目录: $(pwd)
    ❌ 环境信息:
       - PLATFORM: ${PLATFORM:-未设置}
       - ENV_NAME: ${ENV_NAME:-未设置}
       - WORKSPACE: ${WORKSPACE:-未设置}
       - Python可用性: $(command -v python >/dev/null 2>&1 && echo "python: $(python --version 2>&1)" || echo "python: 不可用")$(command -v python3 >/dev/null 2>&1 && echo " | python3: $(python3 --version 2>&1)" || echo " | python3: 不可用")
       - Conda可用性: $(command -v conda >/dev/null 2>&1 && echo "conda: $(conda --version 2>&1)" || echo "conda: 不可用")
       - 当前激活环境: ${CONDA_DEFAULT_ENV:-无}
    ====================================
    "
        
        # 输出到控制台
        echo "$error_details" >&2
        
        # 保存到日志文件(如果已设置)
        if [[ -n "${LOG_FILE:-}" && -w "$(dirname "$LOG_FILE")" ]]; then
            echo "$error_details" >> "$LOG_FILE" 2>/dev/null || true
        fi
        
        exit 1
    }
    
    # 增强的错误追踪函数:用于关键操作失败时的详细诊断
    trace_error() {
        local operation="$1"
        local cmd_output="$2"
        local exit_code="${3:-$?}"
        local error_time=$(sh_date '+%Y-%m-%d %H:%M:%S %Z')
        
        local trace_details="
    🔍 ========== 错误追踪报告 ==========
    ⏰ 时间: $error_time
    🎯 操作: $operation
    💥 退出码: $exit_code
    📍 位置: ${BASH_SOURCE[1]:-未知}:${BASH_LINENO[0]:-未知}
    📂 工作目录: $(pwd)
    
    📝 命令输出:
    $cmd_output
    
    🔧 环境诊断:
       - PLATFORM: ${PLATFORM:-未设置}
       - ENV_NAME: ${ENV_NAME:-未设置}
       - WORKSPACE: ${WORKSPACE:-未设置}
       - LOG_FILE: ${LOG_FILE:-未设置}
       
    🐍 Python 环境:
       - which python: $(which python 2>/dev/null || echo "未找到")
       - which python3: $(which python3 2>/dev/null || echo "未找到")
       - PYTHONPATH: ${PYTHONPATH:-未设置}
       
    🅰️ Anaconda/Miniconda:
       - which conda: $(which conda 2>/dev/null || echo "未找到")
       - CONDA_DEFAULT_ENV: ${CONDA_DEFAULT_ENV:-未设置}
       - CONDA_PREFIX: ${CONDA_PREFIX:-未设置}
       
    💾 磁盘空间:
    $(df -h . 2>/dev/null | tail -1 || echo "无法获取磁盘信息")
    
    🌐 网络连接测试:
    $(ping -c 1 8.8.8.8 >/dev/null 2>&1 && echo "✅ 网络连接正常" || echo "❌ 网络连接异常")
    ==================================================
    "
        
        # 输出到控制台
        echo "$trace_details" >&2
        
        # 保存到日志文件
        if [[ -n "${LOG_FILE:-}" ]]; then
            echo "$trace_details" >> "$LOG_FILE" 2>/dev/null || true
        fi
    }
    
    ok()    { echo "✅ $1"; }
    
    
    # 平台检测 + 变量初始化
    # === 在变量定义后,立即设置日志并重定向 ===
    # 先通过平台检测确定 LOG_DIR
    detect_platform() {
        case "$OSTYPE" in
            msys*|mingw*|cygwin*)
                echo "local-windows"
                return
                ;;
        esac
        [[ -d "/home/aistudio" ]] && echo "aistudio" && return
        [[ -n "${MODELSCOPE_CACHE:-}" ]] && echo "modelscope" && return
        [[ -n "${SSH_CLIENT:-}" ]] && echo "server" && return
        [[ -d "/mnt/workspace" ]] && echo "server" && return
        echo "local-linux"
    }
    
    setup_paths() {
        case "$PLATFORM" in
            "local-windows")
                DEFAULT_DRIVE="D:/"
                if [[ -w "$DEFAULT_DRIVE" ]]; then
                    WORKSPACE="$DEFAULT_DRIVE/workspace"
                    LOG_DIR="$DEFAULT_DRIVE/logs"
                else
                    WORKSPACE="./workspace"
                    LOG_DIR="./logs"
                fi
                ;;
            "aistudio")
                WORKSPACE="/home/aistudio"
                LOG_DIR="/home/aistudio/logs"
                ;;
            "modelscope")
                WORKSPACE="/mnt/workspace"
                LOG_DIR="/mnt/workspace/logs"
                ;;
            "server"|"local-linux")
                WORKSPACE="./workspace"
                LOG_DIR="./logs"
                ;;
            *)
                warn "未知平台: $PLATFORM,使用默认配置"
                WORKSPACE="./workspace"
                LOG_DIR="./logs"
                ;;
        esac
    }
    
    # 🌐 检测平台
    PLATFORM=$(detect_platform)
    info "🌍 检测到平台: $PLATFORM"
    
    # 🛠 设置路径
    setup_paths
    
    # ✅ 创建目录
    mkdir -p "$WORKSPACE" || {
        error "无法创建 WORKSPACE: $WORKSPACE"
        error "💡 请检查该路径是否存在且有写权限"
    }
    
    mkdir -p "$LOG_DIR" || {
        error "无法创建日志目录: $LOG_DIR"
        error "💡 请检查该路径是否存在且有写权限"
    }
    
    # ✅ 定义日志文件(使用上海时区时间)
    LOG_FILE="$LOG_DIR/setup_env_$(sh_date +%Y%m%d_%H%M%S).log"
    
    # 规范化路径工具:将连续的多个 '/' 合并为一个(保留 UNC 前缀 '//')
    normalize_path() {
        local p="$1"
        # 针对 Windows 下(MSYS/Cygwin)路径做专门处理
        if [[ "${PLATFORM:-}" == "local-windows" || "$p" =~ ^[A-Za-z]: ]]; then
            # 将反斜杠转换为正斜杠
            local out="${p//\\//}"
            # 把连续多个 '/' 合并为一个
            while [[ "$out" == *//* ]]; do out="${out//\/\//\/}"; done
            # 确保驱动器后为单个斜杠,例如 D:/logs 而非 D:logs 或 D://logs
            if [[ "$out" =~ ^([A-Za-z]):/*(.*) ]]; then
                local drive="${BASH_REMATCH[1]}"
                local rest="${BASH_REMATCH[2]}"
                printf '%s' "${drive}:/${rest}"
                return
            fi
            printf '%s' "$out"
            return
        fi
    
        # 默认行为:合并重复斜杠(保留 UNC 前缀 '//')
        if [[ "$p" == '//*' ]]; then
            local lead='//'
            local rest="${p#//}"
            while [[ "$rest" == *//* ]]; do rest="${rest//\/\//\/}"; done
            printf '%s' "$lead$rest"
        else
            local out="$p"
            while [[ "$out" == *//* ]]; do out="${out//\/\//\/}"; done
            printf '%s' "$out"
        fi
    }
    
    # 🎯 智能包检查:效率优先,准确保障
    # 
    # � 验证策略分析:
    #   - pip show 未找到 → 99.9% 准确(直接返回未安装)
    #   - pip show 找到 + 关键包 → 需要 import 验证(torch, numpy等)
    #   - pip show 找到 + 大型包 → 检查 Location 存在性(轻量级)
    #   - pip show 找到 + 普通包 → 直接信任(高效)
    #
    # 🚀 性能优化:
    #   - 90% 包只用 pip show(1-2ms)
    #   - 5% 包加 Location 检查(+1ms)  
    #   - 5% 关键包用 import 验证(+50ms)
    check_package_installed() {
        local package="$1"
        local package_name=""
        
        # 提取包名(去除版本号和其他修饰符)
        if [[ "$package" =~ ^([a-zA-Z0-9_-]+) ]]; then
            package_name="${BASH_REMATCH[1]}"
        else
            package_name="$package"
        fi
        
        # 特殊处理一些包名映射
        case "$package_name" in
            "torch")
                package_name="torch"
                # 对于torch,需要特别检查是否为GPU版本
                if pip show "$package_name" >/dev/null 2>&1; then
                    # 检查是否为GPU版本
                    local torch_gpu_check=""
                    torch_gpu_check=$(python -c "
    try:
        import torch
        version = torch.__version__
        is_gpu = '+cu' in version or torch.cuda.is_available()
        
        # 检查CUDA版本兼容性
        if is_gpu and '+cu' in version:
            # 提取CUDA版本号 (如 +cu118, +cu128)
            cuda_parts = version.split('+cu')
            if len(cuda_parts) > 1:
                cuda_version = cuda_parts[1]
                print('INSTALLED_CUDA_' + cuda_version)
            else:
                print('GPU_VERSION_OK')
        elif is_gpu:
            print('GPU_VERSION_OK')
        else:
            print('CPU_VERSION_ONLY')
    except:
        print('IMPORT_FAILED')
    " 2>/dev/null)
                    
                    # 检查是否需要CUDA版本升级
                    if echo "$torch_gpu_check" | smart_grep -q "GPU_VERSION_OK"; then
                        return 0  # GPU版本已安装且CUDA可用
                    elif echo "$torch_gpu_check" | smart_grep -q "INSTALLED_CUDA_"; then
                        # 检查CUDA版本是否匹配当前环境需求
                        local installed_cuda=$(echo "$torch_gpu_check" | smart_sed 's/INSTALLED_CUDA_//')
                        local required_cuda=""
                        
                        # 从TORCH_INDEX提取需求的CUDA版本
                        if echo "$TORCH_INDEX" | smart_grep -q "cu118"; then
                            required_cuda="118"
                        elif echo "$TORCH_INDEX" | smart_grep -q "cu128"; then
                            required_cuda="128"
                        elif echo "$TORCH_INDEX" | smart_grep -q "cu117"; then
                            required_cuda="117"
                        fi
                        
                        if [ "$installed_cuda" = "$required_cuda" ]; then
                            return 0  # CUDA版本匹配,无需重装
                        else
                            info "🔄 检测到CUDA版本不匹配: 已安装cu$installed_cuda, 需要cu$required_cuda"
                            return 1  # 需要升级CUDA版本
                        fi
                    elif echo "$torch_gpu_check" | smart_grep -q "CPU_VERSION_ONLY"; then
                        # CPU版本已安装,但我们需要GPU版本
                        return 1  # 需要重新安装GPU版本
                    else
                        return 1  # 安装有问题,需要重新安装
                    fi
                else
                    return 1  # 未安装
                fi
                ;;
            "torchvision")
                package_name="torchvision"
                ;;
            "torchaudio") 
                package_name="torchaudio"
                ;;
            "opencv-python"|"opencv-contrib-python")
                package_name="cv2"
                ;;
            "pillow")
                package_name="PIL"
                ;;
            "scikit-learn")
                package_name="sklearn"
                ;;
            "beautifulsoup4")
                package_name="bs4"
                ;;
            "pyyaml")
                package_name="yaml"
                ;;
        esac
        
        # 🚀 高效的包检查策略:平衡效率和准确性
        
        # Step 1: 快速检查 - pip show (高效,覆盖99%的情况)
        local pip_show_result=""
        pip_show_result=$(pip show "$package_name" 2>/dev/null)
        local pip_show_exit_code=$?
        
        # 如果 pip show 显示未安装,直接返回未安装(这个结果是可靠的)
        if [ $pip_show_exit_code -ne 0 ]; then
            return 1  # 未安装,pip show未找到包
        fi
        
        # Step 2: pip show 显示已安装,但需要额外验证的情况
        local need_import_check=false
        
        # 检查是否需要额外验证(仅在这些情况下)
        case "$package_name" in
            # 关键包:安装错误代价高,需要双重验证
            torch|tensorflow|numpy|scipy)
                need_import_check=true
                ;;
            # 大型包:安装时间长,需要确保真正可用
            torchvision|torchaudio|opencv*|pillow)
                # 检查包的Location是否存在(轻量级验证)
                local package_location=""
                package_location=$(echo "$pip_show_result" | smart_grep "Location:" | smart_cut -d' ' -f2)
                if [ -n "$package_location" ] && [ -d "$package_location" ]; then
                    need_import_check=false  # 位置存在,trust pip show
                else
                    need_import_check=true   # 位置不存在,需要import验证
                fi
                ;;
            # 普通包:pip show结果可信,不需要额外验证
            *)
                need_import_check=false
                ;;
        esac
        
        # Step 3: 仅在必要时进行 import 验证(保持高效)
        if [ "$need_import_check" = true ]; then
            # 对关键包进行实际导入测试
            if python -c "import $package_name" >/dev/null 2>&1; then
                return 0  # 双重验证通过,确实已安装
            else
                return 1  # pip show说已安装,但实际导入失败(包损坏)
            fi
        else
            # pip show 结果可信,直接信任
            return 0  # 已安装
        fi
    }
    
    # 🚀 智能包安装函数:过滤已安装的包
    filter_installed_packages() {
        local packages=("$@")
        local uninstalled_packages=()
        local installed_packages=()
        
        # 将信息输出重定向到stderr,避免污染返回值
        echo "🔍 正在检查包安装状态..." >&2
        
        for package in "${packages[@]}"; do
            if check_package_installed "$package"; then
                installed_packages+=("$package")
                echo "ℹ️  ✅ $package - 已安装,跳过" >&2
            else
                uninstalled_packages+=("$package")
                echo "ℹ️  📦 $package - 需要安装" >&2
            fi
        done
        
        # 显示统计信息 - 重定向到stderr
        if [ ${#installed_packages[@]} -gt 0 ]; then
            echo "ℹ️  📊 跳过已安装的包 (${#installed_packages[@]}个): ${installed_packages[*]}" >&2
        fi
        
        if [ ${#uninstalled_packages[@]} -gt 0 ]; then
            echo "ℹ️  ⬇️  需要安装的包 (${#uninstalled_packages[@]}个): ${uninstalled_packages[*]}" >&2
        else
            echo "ℹ️  🎉 所有包都已安装,无需下载!" >&2
        fi
        
        # 返回未安装的包列表(仅包名,无额外输出)
        for pkg in "${uninstalled_packages[@]}"; do
            echo "$pkg"
        done
    }
    
    # 规范化 LOG_DIR 和 LOG_FILE,避免出现 D://logs 这样的路径
    LOG_DIR=$(normalize_path "$LOG_DIR")
    LOG_FILE=$(normalize_path "$LOG_FILE")
    
    # ✅ 开始重定向(从现在开始,所有输出都进日志)
    # 优先使用 tee 将输出同时写到日志和控制台(需要 bash 的 process substitution)
    if command -v tee >/dev/null 2>&1; then
        # 将 stdout/stderr 都通过 tee 追加到日志文件,并继续在控制台显示
        if ! exec > >(tee -a "$LOG_FILE") 2> >(tee -a "$LOG_FILE" >&2); then
            echo "❌ 无法通过 tee 重定向到日志文件: $LOG_FILE" >&2
            exit 1
        fi
    else
        # 如果系统没有 tee,提醒用户并保持在控制台输出(推荐:安装 tee 或使用外部管道运行脚本)
        cat >&2 <<'EOF'
    ⚠️  未检测到系统命令 "tee"。
    
    为保证同时在控制台显示并写入日志,建议执行以下任一操作:
     1) 在系统上安装 tee(Ubuntu/Debian: sudo apt update && sudo apt install coreutils -y)。
     2) 或在运行脚本时使用外部管道:
          bash setup_train_env.sh 2>&1 | tee -a "${LOG_FILE}"
    
    脚本将继续在控制台输出(不再自动把所有输出重定向到日志文件),
    如果你选择使用外部管道运行,日志会被完整保存到上面的文件。
    EOF
        # 不执行 exec 重定向,保留控制台输出,按用户要求不自动改为 FIFO 回退
    fi
    
    # 🌟 此后所有输出都记录在日志中
    echo "----------------------------------------"
    info "✅ 日志重定向已生效"
    info "✅ 日志文件已创建: $LOG_FILE"
    info "🔧 开始执行后续安装步骤..."
    echo "----------------------------------------"
    log "安装脚本开始执行"
    
    # 🔍 检测虚拟环境支持情况
    echo "----------------------------------------"
    check_virtual_env_support
    if [ $? -ne 0 ]; then
        warn "⚠️  虚拟环境支持不完整,脚本可能无法正常创建环境"
        warn "💡 建议先安装虚拟环境工具再继续"
    fi
    echo "----------------------------------------"
    
    PYTHON_VERSIONS=("3.10.13" "3.9" "3.8" "3.7")
    
    # -----------------------------
    # 🔍 检查 Conda 是否可用,否则使用 venv
    # -----------------------------
    create_or_use_env() {
        local env_name=$1
        local py_versions=("${@:2}")
    
        # 定义统一路径(用于 venv 和 Linux 上的 Conda)
        ENV_ROOT="$WORKSPACE/envs"
        ENV_PATH="$ENV_ROOT/$env_name"
    
        # -----------------------------
        # 1. 检查 Conda 是否可用
        # -----------------------------
        if command -v conda &> /dev/null; then
            # 判断是否是 Linux 系统
            if [[ "$OSTYPE" == "linux-gnu"* ]]; then
                info "✅ Linux + Conda:使用统一路径 $ENV_PATH"
    
                # 检查指定路径的环境是否存在且完整
                if [ -d "$ENV_PATH" ] && [ -f "$ENV_PATH/bin/python" ]; then
                    ok "Conda 环境已存在: $ENV_PATH"
                else
                    # 清理残缺环境
                    if [ -d "$ENV_PATH" ]; then
                        warn "⚠️  环境目录不完整,正在清理: $ENV_PATH"
                        rm -rf "$ENV_PATH"
                    fi
    
                    info "🆕 创建 Conda 环境: $ENV_PATH"
                    local creation_output=""
                    local creation_failed=false
                    for py_ver in "${py_versions[@]}"; do
                        creation_output=$(conda create -p "$ENV_PATH" python="$py_ver" --yes -v 2>&1)
                        if [ $? -eq 0 ]; then
                            ok "✅ Conda 环境创建成功"
                            creation_failed=false
                            break
                        else
                            creation_failed=true
                        fi
                    done
    
                    if [ "$creation_failed" = true ] || [ ! -f "$ENV_PATH/bin/python" ]; then
                        trace_error "Conda 环境创建失败" "$creation_output"
                        error "Conda 环境创建失败: $ENV_PATH"
                        exit 1
                    fi
                fi
    
                # 激活 Conda 环境(使用完整路径)
                local activation_output=""
                eval "$(conda shell.bash hook)" 2>/dev/null || true
                activation_output=$(conda activate "$ENV_PATH" 2>&1)
                local activation_exit_code=$?
                if [ $activation_exit_code -ne 0 ]; then
                    trace_error "Conda 环境激活失败" "$activation_output" "$activation_exit_code"
                    error "Conda 环境激活失败: $ENV_PATH"
                fi
                return $activation_exit_code
    
            else
                # ✅ 非 Linux(如 Windows),使用 Conda 默认路径
                info "✅ Conda 可用(非 Linux),使用默认路径: $env_name"
    
                if conda env list | smart_grep -E "^$env_name[[:space:]]" > /dev/null; then
                    ok "Conda 环境已存在: $env_name"
                else
                    info "🆕 创建 Conda 环境: $env_name"
                    local conda_creation_output=""
                    conda_creation_output=$(conda create -n "$env_name" python="${py_versions[0]}" --yes 2>&1)
                    local conda_creation_exit_code=$?
                    if [ $conda_creation_exit_code -ne 0 ]; then
                        trace_error "Conda 环境创建失败 (非Linux)" "$conda_creation_output" "$conda_creation_exit_code"
                        error "Conda 环境创建失败: $env_name"
                    fi
                fi
    
                local conda_activation_output=""
                eval "$(conda shell.bash hook)" 2>/dev/null || true
                conda_activation_output=$(conda activate "$env_name" 2>&1)
                local conda_activation_exit_code=$?
                if [ $conda_activation_exit_code -ne 0 ]; then
                    trace_error "Conda 环境激活失败 (非Linux)" "$conda_activation_output" "$conda_activation_exit_code"
                    error "Conda 环境激活失败: $env_name"
                fi
                return $conda_activation_exit_code
            fi
    
        # -----------------------------
        # 2. Conda 不可用,使用 venv(Linux 和 Windows 都用统一路径)
        # -----------------------------
        else
            info "⚠️  Conda 未安装,使用 venv: $ENV_PATH"
    
            if [ -d "$ENV_PATH" ]; then
                if [ -f "$ENV_PATH/bin/activate" ] && [ -f "$ENV_PATH/bin/python" ]; then
                    ok "✅ venv 环境已存在且完整"
                else
                    warn "⚠️  venv 不完整,正在清理"
                    rm -rf "$ENV_PATH"
                fi
            fi
    
            if [ ! -d "$ENV_PATH" ]; then
                mkdir -p "$ENV_ROOT"
                local success=false
                local venv_creation_output=""
    
                for py_ver in "${py_versions[@]}"; do
                    if command -v "python$py_ver" &> /dev/null; then
                        venv_creation_output=$(python"$py_ver" -m venv "$ENV_PATH" 2>&1)
                        if [ $? -eq 0 ]; then
                            success=true
                            break
                        fi
                    elif command -v "python${py_ver%.*}" &> /dev/null; then
                        venv_creation_output=$(python"${py_ver%.*}" -m venv "$ENV_PATH" 2>&1)
                        if [ $? -eq 0 ]; then
                            success=true
                            break
                        fi
                    fi
                done
    
                if [ "$success" = false ]; then
                    trace_error "标准 venv 创建失败" "$venv_creation_output"
                    info "⚠️  标准 venv 创建失败,使用 --without-pip + 手动安装 pip"
                    local without_pip_output=""
                    without_pip_output=$(python3 -m venv "$ENV_PATH" --without-pip 2>&1)
                    local without_pip_exit_code=$?
                    
                    if [ $without_pip_exit_code -ne 0 ]; then
                        trace_error "venv --without-pip 创建失败" "$without_pip_output" "$without_pip_exit_code"
                        error "❌ 虚拟环境创建完全失败:$ENV_PATH"
                    fi
    
                    if [ -f "$ENV_PATH/bin/python" ]; then
                        info "📥 正在手动安装 pip..."
    
                        # ✅ 使用清华镜像,避免网络问题
                        GET_PIP_URL="https://pypi.tuna.tsinghua.edu.cn/bootstrap/pip/get-pip.py"
                        GET_PIP_PY="/tmp/get-pip-$$.py"
    
                        # ✅ 添加超时,防止卡死
                        local curl_output=""
                        curl_output=$(curl -fsSL --connect-timeout 10 --max-time 30 "$GET_PIP_URL" -o "$GET_PIP_PY" 2>&1)
                        local curl_exit_code=$?
                        
                        if [ $curl_exit_code -eq 0 ]; then
                            local pip_install_output=""
                            pip_install_output=$("$ENV_PATH/bin/python" "$GET_PIP_PY" --quiet --no-warn-script-location 2>&1)
                            local pip_exit=$?
                            rm -f "$GET_PIP_PY"
                            if [ $pip_exit -eq 0 ]; then
                                ok "✅ pip 安装成功"
                            else
                                trace_error "pip 手动安装失败" "$pip_install_output" "$pip_exit"
                                error "❌ pip 安装失败"
                                exit 1
                            fi
                        else
                            trace_error "下载 get-pip.py 失败" "$curl_output" "$curl_exit_code"
                            error "❌ 下载 get-pip.py 失败(URL: $GET_PIP_URL)"
                            error "💡 建议检查网络或更换镜像源"
                            exit 1
                        fi
                    else
                        trace_error "虚拟环境创建失败" "无法创建 $ENV_PATH/bin/python"
                        error "❌ 虚拟环境创建失败:$ENV_PATH/bin/python 不存在"
                        exit 1
                    fi
                fi
            fi
    
            # 激活 venv
            if [ -f "$ENV_PATH/bin/activate" ]; then
                local venv_activation_output=""
                venv_activation_output=$(source "$ENV_PATH/bin/activate" 2>&1)
                local venv_activation_exit_code=$?
                if [ $venv_activation_exit_code -eq 0 ]; then
                    ok "✅ venv 环境激活成功: $ENV_PATH"
                else
                    trace_error "venv 环境激活失败" "$venv_activation_output" "$venv_activation_exit_code"
                    error "❌ venv 激活失败: $ENV_PATH/bin/activate 存在但激活失败"
                    exit 1
                fi
            else
                trace_error "venv 激活文件缺失" "activate 脚本不存在: $ENV_PATH/bin/activate"
                error "❌ venv 激活失败: $ENV_PATH/bin/activate 不存在"
                exit 1
            fi
        fi
    }
    
    # -----------------------------
    # 多源容错安装函数
    # -----------------------------
    # robust_pip_install()调用举例
    # # 安装普通包
    # robust_pip_install "requests" "flask"
    
    # # 安装 PyTorch(带 extra-index-url)
    # robust_pip_install "torch" "torchvision" \
    #     --index-url "https://download.pytorch.org/whl/cu118" \
    #     --extra-index-url "https://pypi.org/simple" \
    #     --trusted-host "pypi.org"
    
    # # 安装私有包
    # robust_pip_install "mypackage" \
    #     --index-url "https://private-pypi.example.com/simple" \
    #     --trusted-host "private-pypi.example.com"
    
    robust_pip_install() {
        local packages=()
        local extra_args=()
        local index_url=""
        local extra_index_url=""
        local trusted_hosts=()
        
        local index_url_next=false
        local extra_index_url_next=false
        local trusted_host_next=false
    
        # 解析参数
        for arg in "$@"; do
            case "$arg" in
                --index-url)
                    index_url_next=true
                    ;;
                --extra-index-url)
                    extra_index_url_next=true
                    ;;
                --trusted-host)
                    trusted_host_next=true
                    ;;
                --*)
                    if $index_url_next; then
                        index_url="$arg"
                        index_url_next=false
                    elif $extra_index_url_next; then
                        extra_index_url="$arg"
                        extra_index_url_next=false
                    elif $trusted_host_next; then
                        trusted_hosts+=("$arg")
                        trusted_host_next=false
                    else
                        extra_args+=("$arg")
                    fi
                    ;;
                *)
                    if $index_url_next; then
                        index_url="$arg"
                        index_url_next=false
                    elif $extra_index_url_next; then
                        extra_index_url="$arg"
                        extra_index_url_next=false
                    elif $trusted_host_next; then
                        trusted_hosts+=("$arg")
                        trusted_host_next=false
                    else
                        packages+=("$arg")
                    fi
                    ;;
            esac
        done
    
        # 如果没传包,直接返回
        if [ ${#packages[@]} -eq 0 ]; then
            warn "⚠️  robust_pip_install: 未指定包"
            return 1
        fi
    
        # 🚀 智能过滤:检查已安装的包,避免重复下载
        local filtered_packages=()
        
        # 使用子shell确保输出分离,并安静地获取过滤结果
        {
            info "🔍 正在检查包安装状态以避免重复下载..."
            readarray -t filtered_packages < <(filter_installed_packages "${packages[@]}")
        }
        
        # 如果所有包都已安装,直接返回成功
        if [ ${#filtered_packages[@]} -eq 0 ]; then
            ok "🎉 所有包都已安装,跳过下载!"
            return 0
        fi
        
        # 更新包列表为需要安装的包
        packages=("${filtered_packages[@]}")
        info "📦 将安装 ${#packages[@]} 个包: ${packages[*]}"
    
        local max_retries=3
        local total_attempts=0
        local max_total_attempts=6
    
        local mirrors=(
            "https://pypi.tuna.tsinghua.edu.cn/simple/|pypi.tuna.tsinghua.edu.cn"
            "https://mirrors.aliyun.com/pypi/simple/|mirrors.aliyun.com"
            "https://pypi.douban.com/simple/|pypi.douban.com"
            "https://download.pytorch.org/whl/cu118|download.pytorch.org"
            "https://pypi.org/simple|pypi.org"
        )
    
        info "🚀 开始安装包: ${packages[*]}"
        
        # 快速检测网络连通性
        info "🌐 检测网络连接..."
        local network_ok=false
        for test_host in "pypi.tuna.tsinghua.edu.cn" "mirrors.aliyun.com" "pypi.org"; do
            if ping -c 1 -W 3 "$test_host" >/dev/null 2>&1; then
                network_ok=true
                info "✅ 网络连接正常 (测试主机: $test_host)"
                break
            fi
        done
        
        if [ "$network_ok" = false ]; then
            warn "⚠️  网络连接检测失败,但仍尝试安装"
        fi
    
        local failed_packages=()
        local current_packages=("${packages[@]}")
        local mirror_index=0
    
        while [ ${#current_packages[@]} -gt 0 ] && [ $total_attempts -lt $max_total_attempts ]; do
            ((total_attempts++))
    
            # 在每次尝试前再次过滤已安装的包(防止长时间下载已存在的 wheel)
            # 允许 package 规格(如 pkg==1.2.3 或 pkg[extra])被规整为基础包名再检查
            local to_install=()
            local skipped=()
            for pkg in "${current_packages[@]}"; do
                # 规范化包名:去掉版本约束和 extras
                local pkg_base="$pkg"
                pkg_base=$(echo "$pkg_base" | smart_sed -E 's/([<>=!].*)$//')
                pkg_base=$(echo "$pkg_base" | smart_sed -E 's/\[.*\]//')
    
                if check_package_installed "$pkg_base"; then
                    skipped+=("$pkg")
                else
                    to_install+=("$pkg")
                fi
            done
    
            if [ ${#skipped[@]} -gt 0 ]; then
                info "ℹ️  跳过已安装的包: ${skipped[*]}"
            fi
    
            # 如果没有需要安装的包,直接退出成功
            if [ ${#to_install[@]} -eq 0 ]; then
                ok "🎉 剩余包均已安装,跳过下载和安装。"
                return 0
            fi
    
            # 将当前安装列表替换为需要安装的包
            current_packages=("${to_install[@]}")
    
            if [ $mirror_index -ge ${#mirrors[@]} ]; then
                local final_failure_details="
    所有镜像源都已尝试完毕,仍有以下包无法安装:
    失败包列表: ${current_packages[*]}
    总尝试次数: $total_attempts
    已尝试的镜像源:"
                for mirror in "${mirrors[@]}"; do
                    IFS='|' read -r mirror_url mirror_host <<< "$mirror"
                    final_failure_details="$final_failure_details
      - $mirror_host ($mirror_url)"
                done
                
                trace_error "包安装完全失败" "$final_failure_details"
                error "❌ 所有源尝试失败,仍无法安装: ${current_packages[*]}"
                return 1
            fi
    
            IFS='|' read -r mirror_url mirror_host <<< "${mirrors[$mirror_index]}"
            info "📦 使用镜像: $mirror_host (第 $total_attempts 次)"
            
            # 根据包的大小调整时间预估
            local estimated_time="1-3 分钟"
            for pkg in "${current_packages[@]}"; do
                case "$pkg" in
                    torch|torchvision|torchaudio)
                        estimated_time="10-15 分钟"
                        break
                        ;;
                    tensorflow*|numpy|scipy|pandas)
                        estimated_time="3-8 分钟"
                        break
                        ;;
                esac
            done
            
            # 显示即将执行的包安装
            info "⏳ 正在安装: ${current_packages[*]} (预计需要 ${estimated_time})"
    
            # 根据包大小设置超时时间
            local timeout_seconds=120
            # 检查是否包含大型包(PyTorch相关)
            for pkg in "${current_packages[@]}"; do
                case "$pkg" in
                    torch|torchvision|torchaudio|tensorflow|tensorflow-gpu)
                        timeout_seconds=1800  # 30分钟,足够下载大型包
                        info "🔄 检测到大型包 $pkg,延长超时时间至 30 分钟"
                        break
                        ;;
                esac
            done
    
            # 构造完整的 pip install 命令(使用数组避免引号问题)
            local pip_cmd=("pip" "install" "--no-cache-dir" "--timeout" "$timeout_seconds")
            
            # 添加进度显示参数
            pip_cmd+=( "--progress-bar" "on" )     # 启用进度条 (on/off/raw,pretty无效)
            pip_cmd+=( "--verbose" )               # 显示详细信息包括下载速度
            
            # 添加其他参数
            pip_cmd+=( "${extra_args[@]}" )
            
            # 添加 index-url
            pip_cmd+=( "--index-url" "$mirror_url" )
            pip_cmd+=( "--trusted-host" "$mirror_host" )
            
            # 添加额外的 index-url(如果存在)
            if [ -n "$extra_index_url" ]; then
                pip_cmd+=( "--extra-index-url" "$extra_index_url" )
            fi
            
            # 添加所有 trusted-host(来自参数)
            for host in "${trusted_hosts[@]}"; do
                pip_cmd+=( "--trusted-host" "$host" )
            done
            
            # 构建安装包列表时,避免把 torchvision/torchaudio 在 torch 已存在时与其它包一起安装
            # 因为 pip 在依赖解析时可能会重新下载 torch。我们将把需要 --no-deps 的包单独安装。
            local bulk_pkgs=()
            local nodeps_pkgs=()
            for pkg in "${current_packages[@]}"; do
                case "$pkg" in
                    torchvision|torchaudio)
                        # 如果 torch 已安装且可 import,则单独安装这些包并使用 --no-deps
                        if check_package_installed "torch"; then
                            nodeps_pkgs+=("$pkg")
                        else
                            bulk_pkgs+=("$pkg")
                        fi
                        ;;
                    *)
                        bulk_pkgs+=("$pkg")
                        ;;
                esac
            done
    
            # 默认将 bulk_pkgs 加入主 pip_cmd
            if [ ${#bulk_pkgs[@]} -gt 0 ]; then
                pip_cmd+=( "${bulk_pkgs[@]}" )
            fi
    
            # 显示完整命令(调试用)
            if [[ "${DEBUG:-0}" -eq 1 ]]; then
                info "🔧 执行命令: ${pip_cmd[*]}"
            fi
    
            # 执行命令并显示实时进度
            local pip_install_output=""
            local pip_install_exit_code
            
            info "⚡ 开始下载和安装..."
            info "💡 提示: 按 Ctrl+C 可跳过当前镜像安装 ${current_packages[*]} 并尝试下一个 (不会退出脚本)"
            
            # 如果包含大型包,提供更详细的信息
            if [ "$is_large_package" = true ]; then
                info "📥 检测到大型包,可能需要下载 100MB+ 文件"
                info "🚀 将显示详细的下载进度和速度信息"
                info "⏰ 预计下载时间: 1-10分钟 (取决于网络速度)"
            fi
            
            # 启动后台进度提示任务(仅对大型包)
            local progress_pid=""
            local is_large_package=false
            for pkg in "${current_packages[@]}"; do
                case "$pkg" in
                    torch|torchvision|torchaudio|tensorflow|tensorflow-gpu)
                        is_large_package=true
                        break
                        ;;
                esac
            done
            
            if [ "$is_large_package" = true ]; then
                # 启动后台进度提示
                (
                    local count=0
                    while true; do
                        sleep 60  # 每分钟提示一次
                        count=$((count + 1))
                        echo "⏳ 大型包下载中... (已等待 ${count} 分钟,请继续等待或按 Ctrl+C 跳过此镜像)"
                    done
                ) &
                progress_pid=$!
            fi
            
            # 设置局部的 SIGINT 处理,只影响这个安装过程
            local pip_interrupted=false
            local original_trap=$(trap -p INT)
            
            # 定义中断处理函数
            handle_pip_interrupt() {
                pip_interrupted=true
                # 停止后台进度提示
                if [ -n "$progress_pid" ]; then
                    kill "$progress_pid" 2>/dev/null || true
                    wait "$progress_pid" 2>/dev/null || true
                fi
                echo ""
                warn "⚠️  用户中断安装 ${current_packages[*]},将尝试下一个镜像..."
                return 0
            }
            
            # 设置新的中断处理
            trap 'handle_pip_interrupt' INT
            
            # 执行 pip 安装,显示实时进度
            local start_time=$(date +%s)
            "${pip_cmd[@]}" 2>&1 | while read -r line; do
                # 检查是否被中断
                if [ "$pip_interrupted" = true ]; then
                    break
                fi
                
                # 显示进度信息和时间戳
                local current_time=$(date +%s)
                local elapsed_time=$((current_time - start_time))
                local time_str="[${elapsed_time}s]"
                
                case "$line" in
                    *"Downloading"*|*"downloading"*)
                        # 提取文件大小信息
                        if [[ "$line" =~ ([0-9]+(\.[0-9]+)?[[:space:]]*[MGK]B) ]]; then
                            local file_size="${BASH_REMATCH[1]}"
                            echo "📥 $time_str $line"
                            # 大文件特别提示
                            if [[ "$line" =~ [0-9]+(\.[0-9]+)?[[:space:]]*MB && "$line" =~ torch ]]; then
                                echo "⏳ 正在下载大型 PyTorch 文件 ($file_size),请耐心等待..."
                            fi
                        else
                            echo "📥 $time_str $line"
                        fi
                        ;;
                    *"Installing"*|*"installing"*)
                        echo "📦 $time_str $line"
                        ;;
                    *"Successfully installed"*)
                        echo "✅ $time_str $line"
                        ;;
                    *"Collecting"*)
                        echo "🔍 $line"
                        ;;
                    *"Building"*|*"building"*)
                        echo "🔨 $time_str $line"
                        ;;
                    # 新增:识别pip进度条
                    *"%"*|*"━"*|*"█"*)
                        # 检查是否是进度条(包含百分比或进度字符)
                        if [[ "$line" =~ [0-9]+% ]] || [[ "$line" =~ [━█▌▎] ]]; then
                            echo "⏬ $time_str $line"
                        else
                            echo "$line"
                        fi
                        ;;
                    # 新增:识别下载速度信息
                    *"MB/s"*|*"KB/s"*|*"kB/s"*|*"mB/s"*)
                        echo "🚀 $time_str $line"
                        ;;
                    # 新增:识别文件大小信息
                    *" MB"*|*" KB"*|*" GB"*)
                        if [[ "$line" =~ (Downloading|downloading) ]]; then
                            echo "📥 $time_str $line"
                        else
                            echo "📊 $time_str $line"
                        fi
                        ;;
                    *"ERROR"*|*"Error"*|*"error"*)
                        echo "❌ $time_str $line" >&2
                        ;;
                    *"WARNING"*|*"Warning"*|*"warning"*)
                        echo "⚠️  $time_str $line"
                        ;;
                    *)
                        # 检查是否包含重要信息
                        if [[ "$line" =~ (Processing|Preparing|Cached|Found|Using) ]]; then
                            echo "ℹ️  $line"
                        else
                            # 其他信息正常显示
                            echo "$line"
                        fi
                        ;;
                esac
            done
            
            # 获取退出码
            pip_install_exit_code=${PIPESTATUS[0]}
    
            # 如果 bulk 安装成功且存在需要单独安装的 nodeps_pkgs,则单独安装它们,使用 --no-deps
            if [ $pip_install_exit_code -eq 0 ] && [ ${#nodeps_pkgs[@]} -gt 0 ]; then
                info "📦 开始单独安装不带依赖的包: ${nodeps_pkgs[*]} (使用 --no-deps,避免触发 torch 重下载)"
                local nodeps_cmd=("pip" "install" "--no-deps" "--no-cache-dir" "--timeout" "$timeout_seconds" "--progress-bar" "on" "--verbose" "--index-url" "$mirror_url" "--trusted-host" "$mirror_host")
                if [ -n "$extra_index_url" ]; then
                    nodeps_cmd+=("--extra-index-url" "$extra_index_url")
                fi
                for host in "${trusted_hosts[@]}"; do
                    nodeps_cmd+=("--trusted-host" "$host")
                done
                nodeps_cmd+=("${nodeps_pkgs[@]}")
    
                # 执行 nodeps 安装并显示输出
                "${nodeps_cmd[@]}" 2>&1 | while read -r nline; do
                    echo "$nline"
                done
                local nodeps_exit=${PIPESTATUS[0]}
                if [ $nodeps_exit -ne 0 ]; then
                    warn "⚠️  单独安装 ${nodeps_pkgs[*]} 失败 (exit $nodeps_exit),将视为当前镜像失败并尝试下一个镜像"
                    pip_install_exit_code=1
                else
                    ok "✅ 单独安装 ${nodeps_pkgs[*]} 成功"
                fi
            fi
            
            # 停止后台进度提示
            if [ -n "$progress_pid" ]; then
                kill "$progress_pid" 2>/dev/null || true
                wait "$progress_pid" 2>/dev/null || true
            fi
            
            # 检查是否被用户中断
            if [ "$pip_interrupted" = true ]; then
                pip_install_exit_code=130  # 用户中断退出码
                pip_install_output="用户中断安装"
            fi
            
            # 恢复原来的中断处理
            if [ -n "$original_trap" ]; then
                eval "$original_trap"
            else
                trap - INT
            fi
            
            if [ $pip_install_exit_code -eq 0 ]; then
                local end_time=$(date +%s)
                local elapsed_time=$((end_time - start_time))
                local elapsed_min=$((elapsed_time / 60))
                local elapsed_sec=$((elapsed_time % 60))
                
                if [ $elapsed_time -gt 60 ]; then
                    ok "✅ 所有包安装成功 (耗时: ${elapsed_min}分${elapsed_sec}秒)"
                else
                    ok "✅ 所有包安装成功 (耗时: ${elapsed_time}秒)"
                fi
                
                # 如果是大型包,显示额外的性能信息
                if [ "$is_large_package" = true ]; then
                    info "📊 大型包安装完成统计:"
                    info "   ⏱️  总耗时: ${elapsed_min}分${elapsed_sec}秒"
                    info "   📡 使用镜像: $mirror_host"
                    info "   📦 包数量: ${#current_packages[@]}"
                fi
                
                return 0
            elif [ $pip_install_exit_code -eq 124 ]; then
                local timeout_msg="⏰ 镜像 $mirror_host 安装 ${current_packages[*]} 超时 (${timeout_seconds}秒),尝试下一个镜像"
                warn "$timeout_msg"
                # 记录详细的超时信息到日志
                local timeout_details="
    超时详情:
    - 镜像: $mirror_host
    - 超时时间: ${timeout_seconds}秒 ($(echo "scale=1; ${timeout_seconds}/60" | bc 2>/dev/null || echo "$((timeout_seconds/60))")分钟)
    - 包列表: ${current_packages[*]}
    - 时间: $(sh_date)
    - 建议: 尝试使用更快的网络或减少包数量"
                echo "$timeout_details" | tee -a "${LOG_FILE:-/dev/null}" >/dev/null
                trace_error "pip 安装超时 (镜像: $mirror_host, 包: ${current_packages[*]})" "$timeout_details" "124"
            elif [ $pip_install_exit_code -eq 130 ]; then
                warn "🔄 用户跳过镜像 $mirror_host (安装 ${current_packages[*]}),尝试下一个镜像"
            else
                warn "⚠️  镜像 $mirror_host 安装 ${current_packages[*]} 失败,尝试下一个镜像"
                if [[ "${DEBUG:-0}" -eq 1 ]]; then
                    local mirror_failure_details="
    镜像: $mirror_host
    包列表: ${current_packages[*]}
    命令: ${pip_cmd[*]}
    退出码: $pip_install_exit_code
    输出:
    $pip_install_output"
                    trace_error "pip 安装失败 (镜像: $mirror_host, 包: ${current_packages[*]})" "$mirror_failure_details" "$pip_install_exit_code"
                fi
            fi
            
            failed_packages=()
            for pkg in "${current_packages[@]}"; do
                if ! pip show "$pkg" &> /dev/null; then
                    failed_packages+=("$pkg")
                fi
            done
            current_packages=("${failed_packages[@]}")
            ((mirror_index++))
            
            # 如果不是超时或中断,等待一下再尝试下一个镜像
            if [ $pip_install_exit_code -ne 124 ] && [ $pip_install_exit_code -ne 130 ]; then
                sleep 2
            fi
        done
    
        if [ ${#current_packages[@]} -gt 0 ]; then
            error "❌ 安装失败: ${current_packages[*]}"
            return 1
        fi
    
        ok "✅ 安装完成"
        return 0
    }
    
    # 🔧 封装:安装 GPU 版 PyTorch 的函数
    # 在调用 install_torch_gpu() 前可用:
    #   export TORCH_INDEX="https://download.pytorch.org/whl/cu118"
    # 支持源:
    #   # 使用官方源(推荐)
    #   export TORCH_INDEX="https://download.pytorch.org/whl/cu118"
    #   # 使用阿里云镜像(可选)
    #   export TORCH_INDEX="https://mirrors.aliyun.com/pytorch-wheels/cu118/"
    install_torch_gpu() {
        local index_url="${1:-$TORCH_INDEX}"
    
        # 提示用户使用了默认值
        if [ -z "$TORCH_INDEX" ] && [ -z "${1:-}" ]; then
            warn "⚠️  TORCH_INDEX 未设置,使用默认源: https://download.pytorch.org/whl/cu118"
        fi
    
        # 设置默认值
        : "${index_url:=https://download.pytorch.org/whl/cu118}"
    
        info "🚀 安装 GPU 版 PyTorch: torch torchaudio torchvision"
        info "🔗 主源: $index_url"
        info "📦 备用源: https://pypi.org/simple"
    
        if robust_pip_install \
            "torch" "torchaudio" "torchvision" \
            --index-url "$index_url" \
            --extra-index-url "https://pypi.org/simple" \
            --trusted-host "pypi.org" \
            --trusted-host "$(echo "$index_url" | awk -F[/:] '{print $4}')" \
        ; then
            ok "✅ GPU 版 PyTorch 安装成功"
            return 0
        else
            local torch_failure_details="
    PyTorch GPU 版本安装失败详情:
    主源: $index_url  
    备用源: https://pypi.org/simple
    包列表: torch torchaudio torchvision
    
    可能的原因:
    1. 网络连接问题 (访问 PyTorch 官方源失败)
    2. CUDA 版本不匹配 (请检查本机 CUDA 版本)
    3. Python 版本不兼容
    4. 磁盘空间不足
    
    建议的解决方案:
    1. 检查 CUDA 版本: nvidia-smi 或 nvcc --version
    2. 手动指定 CUDA 版本,如: 
       export TORCH_INDEX='https://download.pytorch.org/whl/cu117'
    3. 降级到 CPU 版本: pip install torch torchaudio torchvision
    4. 检查网络代理设置"
            
            trace_error "GPU 版 PyTorch 安装失败" "$torch_failure_details"
            error "❌ GPU 版 PyTorch 安装失败"
            return 1
        fi
    }
    
    # 🔧 通用 PyTorch 冲突保护安装器
    # 功能: 使用 --no-deps 安装包,然后智能安装非冲突依赖
    # 用法: install_with_torch_protection "package_name" [excluded_packages...]
    install_with_torch_protection() {
        local target_package="$1"
        shift
        local excluded_packages=("$@")
        
        # 默认的 PyTorch 相关排除列表
        local default_torch_exclusions=(
            "torch" "torchvision" "torchaudio" "torchtext" 
            "pytorch-lightning" "torch-audio" "torchdiffeq"
            "torchmetrics" "torchsde" "torch-optimizer"
            "torch-stoi" "pytorch-ranger" "ema-pytorch"
            "vector-quantize-pytorch" "clip-anytorch"
            "dctorch" "kornia"
        )
        
        # 合并排除列表
        local all_exclusions=("${default_torch_exclusions[@]}" "${excluded_packages[@]}")
        
        info "🛡️  开始保护性安装: $target_package"
        info "🚫 排除包列表: ${all_exclusions[*]}"
        
        # Step 1: 检查包是否已安装
        if pip show "$target_package" &> /dev/null; then
            info "✅ $target_package 已安装,跳过"
            return 0
        fi
        
        # Step 2: 使用 --no-deps 安装目标包
        info "📦 使用 --no-deps 安装 $target_package(避免依赖冲突)"
        if ! robust_pip_install "--no-deps" "$target_package"; then
            trace_error "$target_package 安装失败" "robust_pip_install --no-deps $target_package 返回失败"
            error "❌ $target_package 安装失败"
            return 1
        fi
        
        ok "✅ $target_package 安装成功(已跳过依赖以保护 PyTorch)"
        
        # Step 3: 智能安装依赖
        info "🔍 智能安装 $target_package 依赖(排除冲突包)..."
        install_package_deps "$target_package" "${all_exclusions[@]}"
        
        return 0
    }
    
    # 🛡️ 保护性pip安装函数:防止已安装核心包被依赖重装
    # 用法: protected_pip_install "package1" "package2" [pip_args...]
    protected_pip_install() {
        local packages=("$@")
        local pip_args=()
        local install_packages=()
        
        # 分离包名和pip参数
        for arg in "${packages[@]}"; do
            if [[ "$arg" =~ ^-- ]]; then
                pip_args+=("$arg")
            else
                install_packages+=("$arg")
            fi
        done
        
        info "🛡️ 保护性安装: ${install_packages[*]}"
        
        # 检查是否有已保护的核心包
        local has_protected=false
        if [ -n "${PROTECTED_CORE_PACKAGES:-}" ] && [ ${#PROTECTED_CORE_PACKAGES[@]} -gt 0 ]; then
            for pkg in "${install_packages[@]}"; do
                for protected in "${PROTECTED_CORE_PACKAGES[@]}"; do
                    if [ "$pkg" = "$protected" ]; then
                        warn "🛡️ 检测到保护包 $pkg,使用 --no-deps 防止依赖重装"
                        has_protected=true
                        break 2
                    fi
                done
            done
        fi
        
        # 如果包含保护包,使用 --no-deps 安装
        if [ "$has_protected" = true ]; then
            info "🚫 使用 --no-deps 模式保护已安装核心包"
            robust_pip_install "${install_packages[@]}" "${pip_args[@]}" --no-deps
        else
            # 正常安装
            robust_pip_install "${install_packages[@]}" "${pip_args[@]}"
        fi
    }
    
    # 🔧 智能依赖安装器(通用版本)
    # 功能: 获取包的依赖列表,排除指定包,安装其余依赖
    # 用法: install_package_deps "package_name" excluded_package1 excluded_package2 ...
    install_package_deps() {
        local target_package="$1"
        shift
        local excluded_packages=("$@")
        
        info "🔍 获取 $target_package 的实际依赖列表..."
        
        # 方法1: 尝试从 pip show 获取依赖信息
        local actual_deps=""
        actual_deps=$(pip show "$target_package" 2>/dev/null | grep "Requires:" | sed 's/Requires: //' | tr ',' '\n' | sed 's/^ *//;s/ *$//' | grep -v '^$')
        
        # 方法2: 如果方法1失败,尝试使用 pipdeptree (如果可用)
        if [ -z "$actual_deps" ] && command -v pipdeptree >/dev/null 2>&1; then
            info "📋 使用 pipdeptree 获取依赖..."
            actual_deps=$(pipdeptree --packages "$target_package" --json 2>/dev/null | python -c "
    import sys, json
    try:
        data = json.load(sys.stdin)
        for pkg in data:
            if pkg['package']['key'] == '$target_package':
                deps = [dep['key'] for dep in pkg['dependencies']]
                print('\n'.join(deps))
                break
    except:
        pass
    " 2>/dev/null)
        fi
        
        # 方法3: 使用包特定的已知依赖列表
        if [ -z "$actual_deps" ]; then
            info "📋 使用预定义的 $target_package 依赖列表..."
            case "$target_package" in
                "prefigure")
                    actual_deps="tqdm
    einops
    matplotlib
    numpy
    Pillow
    scipy
    accelerate
    diffusers
    transformers"
                    ;;
                "pytorch-lightning")
                    actual_deps="torch
    torchmetrics
    lightning-utilities
    typing-extensions
    fsspec
    packaging
    pyyaml
    tqdm"
                    ;;
                "diffusers")
                    actual_deps="torch
    transformers
    numpy
    Pillow
    requests
    regex
    importlib-metadata
    huggingface-hub
    accelerate
    safetensors"
                    ;;
                "speechbrain")
                    actual_deps="torch
    torchaudio
    numpy
    scipy
    tqdm
    joblib
    ruamel.yaml
    hyperpyyaml
    sentencepiece
    huggingface-hub"
                    ;;
                "asteroid")
                    actual_deps="torch
    torchaudio
    numpy
    scipy
    pandas
    soundfile
    torch-stoi
    torch-optimizer
    pytorch-lightning
    huggingface-hub"
                    ;;
                *)
                    # 通用的机器学习包常见依赖
                    actual_deps="numpy
    scipy
    matplotlib
    pandas
    tqdm
    Pillow
    requests
    packaging
    typing-extensions"
                    ;;
            esac
        else
            info "📋 从包信息获取到依赖列表"
        fi
        
        if [ -z "$actual_deps" ]; then
            warn "⚠️  无法获取 $target_package 的依赖信息,跳过依赖安装"
            return 0
        fi
        
        # 处理每个依赖
        local installed_count=0
        local skipped_count=0
        local failed_count=0
        
        while IFS= read -r dep; do
            [ -z "$dep" ] && continue
            
            # 清理依赖名称(去掉版本要求)
            local clean_dep=$(echo "$dep" | sed 's/[<>=!].*//' | sed 's/^ *//;s/ *$//')
            [ -z "$clean_dep" ] && continue
            
            # 检查是否在排除列表中
            local is_excluded=false
            for excluded_pkg in "${excluded_packages[@]}"; do
                if [[ "$clean_dep" == "$excluded_pkg"* ]] || [[ "$clean_dep" == *"$excluded_pkg"* ]]; then
                    is_excluded=true
                    break
                fi
            done
            
            if [ "$is_excluded" = true ]; then
                info "⏭️  跳过排除的依赖: $clean_dep"
                ((skipped_count++))
                continue
            fi
            
            # 检查是否已安装
            if pip show "$clean_dep" &> /dev/null; then
                info "✅ $clean_dep 已安装,跳过"
            else
                info "📦 安装 $target_package 依赖: $clean_dep"
                if robust_pip_install "$clean_dep"; then
                    ok "✅ $clean_dep 安装成功"
                    ((installed_count++))
                else
                    warn "⚠️  $clean_dep 安装失败,可能影响 $target_package 功能"
                    ((failed_count++))
                fi
            fi
        done <<< "$actual_deps"
        
        # 显示安装统计
        info "📊 依赖安装统计: 新安装 $installed_count 个,跳过 $skipped_count 个,失败 $failed_count 个"
        
        # 验证目标包是否能正常导入
        info "🔍 验证 $target_package 安装完整性..."
        local import_test=""
        import_test=$(python -c "
    try:
        import $target_package
        print('IMPORT_OK')
        version = getattr($target_package, '__version__', 'unknown')
        print(f'$target_package 版本: {version}')
    except ImportError as e:
        print(f'IMPORT_ERROR: {e}')
    except Exception as e:
        print(f'OTHER_ERROR: {e}')
    " 2>&1)
        
        if echo "$import_test" | grep -q "IMPORT_OK"; then
            echo "$import_test"
            ok "✅ $target_package 及其依赖安装完成,可正常使用"
            return 0
        else
            echo "$import_test"
            warn "⚠️  $target_package 导入测试失败,可能缺少某些依赖"
            return 1
        fi
    }
    
    # 🔧 智能安装 prefigure 依赖(使用通用函数)
    install_prefigure_deps() {
        install_package_deps "prefigure" \
            "torch" "torchvision" "torchaudio" "torchtext" \
            "pytorch-lightning" "torch-audio" "torchdiffeq" \
            "torchmetrics" "torchsde" "torch-optimizer" \
            "torch-stoi" "pytorch-ranger" "ema-pytorch" \
            "vector-quantize-pytorch" "clip-anytorch" \
            "dctorch" "kornia"
    }
    
    # 🛡️ 通用核心包保护安装:确保核心包版本,并保护性安装冲突包
    # 用法:ensure_core_package_installed "core_package" "conflict_package1" ["conflict_package2" ...]
    # 示例:ensure_core_package_installed "torch" "prefigure" "diffusers"
    # 示例:ensure_core_package_installed "tensorflow" "some_tf_conflict_package"
    # 示例:ensure_core_package_installed "numpy" "some_numpy_conflict_package"
    ensure_core_package_installed() {
        local core_package="$1"
        shift
        local conflict_packages=("$@")
        
        if [ -z "$core_package" ]; then
            error "❌ ensure_core_package_installed: 需要指定核心包名"
            return 1
        fi
        
        if [ ${#conflict_packages[@]} -eq 0 ]; then
            error "❌ ensure_core_package_installed: 需要指定至少一个冲突包"
            return 1
        fi
        
        info "🛡️ 开始核心包保护性安装流程"
        info "🎯 核心包: $core_package"
        info "⚠️  冲突包列表: ${conflict_packages[*]}"
        
        # Step 1: 使用统一的包检查函数确保核心包已安装
        info "🔍 检查核心包 $core_package 安装状态..."
        
        if check_package_installed "$core_package"; then
            ok "✅ 检测到核心包 $core_package 已正确安装"
            
            # 显示当前版本信息(通用版)
            local version_info=""
            version_info=$(python -c "
    try:
        import $core_package
        if hasattr($core_package, '__version__'):
            print(f'$core_package 版本: {$core_package.__version__}')
        else:
            print(f'$core_package: 已安装(无版本信息)')
        
        # 特殊处理 torch 的 CUDA 信息
        if '$core_package' == 'torch':
            print(f'CUDA可用: {\"是\" if $core_package.cuda.is_available() else \"否\"}')
            if $core_package.cuda.is_available():
                print(f'GPU数量: {$core_package.cuda.device_count()}')
    except Exception as e:
        print(f'版本检查失败: {e}')
    " 2>/dev/null)
            echo "$version_info"
        else
            info "📦 需要安装核心包 $core_package..."
            
            # 根据核心包类型选择安装策略
            case "$core_package" in
                "torch")
                    if ! install_torch_gpu; then
                        error "❌ PyTorch GPU 版本安装失败"
                        return 1
                    fi
                    ;;
                *)
                    # 通用包安装
                    if ! robust_pip_install "$core_package"; then
                        error "❌ 核心包 $core_package 安装失败"
                        return 1
                    fi
                    ;;
            esac
            ok "✅ 核心包 $core_package 安装完成"
        fi
    
        # Step 2: 循环保护性安装所有冲突包
        for conflict_pkg in "${conflict_packages[@]}"; do
            info "🛡️ 开始保护性安装 $conflict_pkg (避免覆盖核心包 $core_package)"
            
            # 根据核心包类型选择保护策略
            case "$core_package" in
                "torch")
                    if ! install_with_torch_protection "$conflict_pkg"; then
                        warn "⚠️ $conflict_pkg 安装失败,继续处理下一个包"
                        continue
                    fi
                    ;;
                *)
                    # 通用保护策略:使用 --no-deps
                    if ! robust_pip_install "$conflict_pkg" --no-deps; then
                        warn "⚠️ $conflict_pkg 保护性安装失败,继续处理下一个包"
                        continue
                    fi
                    ;;
            esac
            
            ok "✅ $conflict_pkg 保护性安装完成"
        done
    
        # Step 3: 最终验证核心包完整性
        info "🔍 验证核心包 $core_package 是否保持完整"
        local final_check=""
        final_check=$(python -c "
    try:
        import $core_package
        if hasattr($core_package, '__version__'):
            print(f'最终 $core_package 版本: {$core_package.__version__}')
        else:
            print(f'最终 $core_package: 导入成功')
        
        # 特殊验证逻辑
        if '$core_package' == 'torch':
            if $core_package.cuda.is_available():
                print('✅ GPU支持正常')
                print(f'GPU设备: {$core_package.cuda.get_device_name(0)}')
            else:
                print('❌ GPU支持异常')
        else:
            print('✅ 包导入正常')
            
    except Exception as e:
        print(f'❌ 验证失败: {e}')
    " 2>/dev/null)
        
        echo "$final_check"
        
        if echo "$final_check" | grep -q "✅"; then
            ok "🎉 核心包 $core_package 保护性安装流程完成"
            return 0
        else
            error "❌ 核心包 $core_package 验证失败"
            return 1
        fi
    }
    
    # 🛡️ PyTorch 专用保护函数(向后兼容)
    ensure_torch_gpu_be_installed() {
        local conflict_packages=("$@")
        info "🔄 调用通用核心包保护函数处理 PyTorch"
        ensure_core_package_installed "torch" "${conflict_packages[@]}"
    }
    
    # 🛡️ 预防性安装:确保 PyTorch GPU 版本,并保护性安装 prefigure(向后兼容函数)
    install_pytorch_and_prefigure_safely() {
        info "🔄 调用通用核心包保护函数处理 prefigure"
        ensure_core_package_installed "torch" "prefigure"
    }
        info "🛡️ 开始 PyTorch GPU 保护性安装流程"
        
        # Step 1: 使用统一的包检查函数检查 PyTorch GPU 版本
        info "🔍 检查当前 PyTorch 安装状态..."
        
        if check_package_installed "torch"; then
            ok "✅ 检测到 GPU 版本的 PyTorch 已正确安装"
            
            # 显示当前版本信息
            local version_info=""
            version_info=$(python -c "
    try:
        import torch
        print(f'PyTorch版本: {torch.__version__}')
        if torch.cuda.is_available():
            print(f'CUDA可用: 是')
            print(f'GPU数量: {torch.cuda.device_count()}')
        else:
            print(f'CUDA可用: 否')
    except Exception as e:
        print(f'版本检查失败: {e}')
    " 2>/dev/null)
            echo "$version_info"
        else
            info "� 需要安装 GPU 版本的 PyTorch..."
            if ! install_torch_gpu; then
                error "❌ PyTorch GPU 版本安装失败"
                return 1
            fi
            ok "✅ PyTorch GPU 版本安装完成"
        fi
    
        # Step 2: 安装 prefigure(使用通用保护函数)
        info "🛡️  开始保护性安装 prefigure (避免覆盖 PyTorch GPU 版本)"
        if ! install_with_torch_protection "prefigure"; then
            warn "⚠️  prefigure 安装失败,但继续执行后续步骤"
            # 可选:exit 1 如果必须成功
        fi
    
        # Step 4: 验证安装后 PyTorch GPU 版本是否保持完整
        info "🔍 验证 PyTorch GPU 版本是否保持完整"
        local current_torch_check=""
        current_torch_check=$(python -c "
    import torch
    print(f'当前PyTorch版本: {torch.__version__}')
    if torch.cuda.is_available():
        print('CURRENT_GPU_OK')
        print(f'CUDA版本: {torch.version.cuda if hasattr(torch.version, \"cuda\") else \"unknown\"}')
        print(f'GPU设备: {torch.cuda.get_device_name(0)}')
    else:
        print('CURRENT_CPU_ONLY')
    " 2>&1)
        
        local torch_check_exit_code=$?
        
        if [ $torch_check_exit_code -eq 0 ] && echo "$current_torch_check" | grep -q "CURRENT_GPU_OK"; then
            echo "$current_torch_check"
            ok "✅ PyTorch GPU 版本保持完整,prefigure 安装成功"
            return 0
        else
            warn "⚠️  检测到 PyTorch 问题,可能需要重新安装"
            echo "$current_torch_check"
            
            # 如果确实有问题,再重新安装 GPU 版本
            info "🔧 重新安装 GPU 版 PyTorch 以确保完整性"
            if ! install_torch_gpu; then
                trace_error "GPU 版 PyTorch 恢复安装失败" "install_torch_gpu 函数在 prefigure 后调用失败"
                error "❌ GPU 版 PyTorch 安装失败,请检查 CUDA 环境"
                return 1
            fi
        fi
    
        # Step 5: 最终验证 CUDA 是否可用
        info "🔍 最终验证 PyTorch 是否支持 CUDA"
        local cuda_verification_output=""
        cuda_verification_output=$(python -c "
    import torch
    print(f'PyTorch: {torch.__version__}')
    assert torch.cuda.is_available(), 'CUDA not available'
    print(f'✅ CUDA 可用: {torch.cuda.get_device_name(0)}')
    " 2>&1)
        local cuda_verification_exit_code=$?
        
        if [ $cuda_verification_exit_code -eq 0 ]; then
            echo "$cuda_verification_output"
            ok "✅ 成功确保 PyTorch 为 GPU 版"
        else
            local cuda_diagnostic_output=""
            cuda_diagnostic_output=$(python -c "import torch; print(f'CUDA available: {torch.cuda.is_available()}')" 2>&1)
            
            local full_diagnostic="
    CUDA 验证失败详情:
    PyTorch 验证输出:
    $cuda_verification_output
    
    CUDA 可用性诊断:
    $cuda_diagnostic_output
    
    可能的原因:
    1. CUDA 驱动版本不匹配
    2. PyTorch 安装的是 CPU 版本
    3. CUDA 库未正确安装
    4. 系统没有兼容的 GPU
    
    建议的解决方案:
    1. 检查 NVIDIA 驱动: nvidia-smi
    2. 检查 CUDA 版本: nvcc --version
    3. 重新安装对应 CUDA 版本的 PyTorch
    4. 如无 GPU,改用 CPU 版本: pip install torch torchvision torchaudio"
            
            trace_error "PyTorch CUDA 验证失败" "$full_diagnostic" "$cuda_verification_exit_code"
            error "❌ PyTorch 不支持 CUDA,请检查驱动、CUDA、安装版本是否匹配"
            exit 1
        fi
    }
    
    
    # # 🔧 智能升级 pip:仅当版本过低时才升级
    # # 调用函数(使用默认最低版本 23.0)
    # upgrade_pip_if_needed
    # # 或指定最低版本
    # upgrade_pip_if_needed "24.0"
    upgrade_pip_if_needed() {
        local required_version="${1:-23.0}"  # 建议最低版本(可传参)
        local current_version
    
        info "🔍 检查 pip 版本..."
    
        # 获取当前 pip 版本
        local pip_version_output=""
        pip_version_output=$(python -m pip --version 2>&1)
        local pip_version_exit_code=$?
        
        if [ $pip_version_exit_code -eq 0 ]; then
            current_version=$(echo "$pip_version_output" | awk '{print $2}')
        else
            trace_error "pip 版本检查失败" "$pip_version_output" "$pip_version_exit_code"
            warn "⚠️  pip 未安装或无法获取版本,准备安装"
            
            # 先尝试 ensurepip(某些系统不包含)
            local ensurepip_output=""
            ensurepip_output=$(python -m ensurepip --default-pip 2>&1)
            local ensurepip_exit_code=$?
            if [ $ensurepip_exit_code -ne 0 ]; then
                trace_error "ensurepip 安装失败" "$ensurepip_output" "$ensurepip_exit_code"
            fi
            
            current_version=$(python -m pip --version 2>/dev/null | awk '{print $2}')
    
            # 如果仍然没有 pip,则尝试使用 get-pip.py(使用清华镜像以提高可用性)
            if [ -z "$current_version" ]; then
                warn "⚠️ pip 仍未安装,尝试通过 get-pip.py 安装"
                GET_PIP_URL="https://pypi.tuna.tsinghua.edu.cn/bootstrap/pip/get-pip.py"
                GET_PIP_PY="/tmp/get-pip-$$.py"
    
                local download_output=""
                if command -v curl >/dev/null 2>&1; then
                    download_output=$(curl -fsSL --connect-timeout 10 --max-time 60 "$GET_PIP_URL" -o "$GET_PIP_PY" 2>&1)
                    local download_exit_code=$?
                    if [ $download_exit_code -ne 0 ]; then
                        trace_error "curl 下载 get-pip.py 失败" "$download_output" "$download_exit_code"
                    fi
                elif command -v wget >/dev/null 2>&1; then
                    download_output=$(wget -q -O "$GET_PIP_PY" "$GET_PIP_URL" 2>&1)
                    local download_exit_code=$?
                    if [ $download_exit_code -ne 0 ]; then
                        trace_error "wget 下载 get-pip.py 失败" "$download_output" "$download_exit_code"
                    fi
                else
                    trace_error "缺少下载工具" "系统未安装 curl 或 wget,无法下载 get-pip.py"
                    warn "⚠️ 无法下载 get-pip.py:系统未安装 curl 或 wget"
                fi
    
                if [ -f "$GET_PIP_PY" ]; then
                    local get_pip_output=""
                    get_pip_output=$(python "$GET_PIP_PY" --quiet --no-warn-script-location 2>&1)
                    local get_pip_exit_code=$?
                    if [ $get_pip_exit_code -eq 0 ]; then
                        ok "✅ pip 安装成功 (get-pip.py)"
                    else
                        trace_error "get-pip.py 安装失败" "$get_pip_output" "$get_pip_exit_code"
                        warn "⚠️ 使用 get-pip.py 安装 pip 失败"
                    fi
                    rm -f "$GET_PIP_PY"
                fi
    
                current_version=$(python -m pip --version 2>/dev/null | awk '{print $2}')
            fi
        fi
    
        info "📦 当前 pip 版本: $current_version,目标最低版本: $required_version"
    
        # 比较版本(使用 sort -V 进行版本排序比较)
        if printf '%s\n%s' "$required_version" "$current_version" | sort -V | head -n1 | grep -q "$required_version"; then
            ok "✅ pip 版本已满足要求,跳过升级"
            return 0
        else
            info "⏫ pip 版本过低,正在升级..."
            local pip_upgrade_output=""
            local pip_upgrade_exit_code
            
            if [ -n "$PIP_INDEX" ] && [ -n "$PIP_TRUSTED_HOST" ]; then
                pip_upgrade_output=$(python -m pip install --upgrade pip \
                    -i "$PIP_INDEX" \
                    --trusted-host "$PIP_TRUSTED_HOST" 2>&1)
                pip_upgrade_exit_code=$?
            else
                pip_upgrade_output=$(python -m pip install --upgrade pip 2>&1)
                pip_upgrade_exit_code=$?
            fi
    
            if [ $pip_upgrade_exit_code -eq 0 ]; then
                ok "✅ pip 升级成功"
            else
                trace_error "pip 升级失败" "$pip_upgrade_output" "$pip_upgrade_exit_code"
                warn "⚠️  pip 升级失败,但继续执行后续步骤"
            fi
        fi
    }
    
    # -----------------------------
    # 3. 检查或创建环境(Conda 优先,venv fallback)
    # -----------------------------
    ENV_NAME="train_ss"
    
    # 创建或使用已有环境(Conda 或 venv)
    if ! create_or_use_env "$ENV_NAME" "${PYTHON_VERSIONS[@]}"; then
        trace_error "虚拟环境创建/激活完全失败" "create_or_use_env 函数返回非零退出码"
        error "虚拟环境创建或激活失败,脚本终止"
    fi
    
    # 此时环境已激活,无需额外 activate
    info "✅ 环境已激活: $ENV_NAME"
    echo "最新进度请查看日志文件: $LOG_FILE"
    
    
    
    # -----------------------------
    # 5. 升级 pip
    # -----------------------------
    upgrade_pip_if_needed 
    echo "最新进度请查看日志文件: $LOG_FILE"
    
    # -----------------------------
    # 6. 智能安装 PyTorch(根据 GPU)
    # -----------------------------
    info "🔍 检测 GPU..."
    TORCH_INDEX="https://download.pytorch.org/whl/cu128"
    
    if command -v nvidia-smi &> /dev/null; then
        GPU_NAME=$(nvidia-smi --query-gpu=name --format=csv,noheader,nounits -i 0 || echo "unknown")
        info "GPU: $GPU_NAME"
        case "$GPU_NAME" in
            *"P100"*) TORCH_INDEX="https://download.pytorch.org/whl/cu118" ;;
            *"T4"*|*"V100"*) info "使用 CUDA 11.8/12.x" ;;
            *"A10"*|*"A100"*|*"3090"*|*"4090"*) info "使用 CUDA 12.8" ;;
            *) info "未知 GPU,尝试 CUDA 12.8" ;;
        esac
    else
        warn "⚠️  无 nvidia-smi,使用 CPU 版"
        TORCH_INDEX="https://download.pytorch.org/whl/cpu"
    fi
    
    # 🎯 处理核心包参数
    DEFAULT_CORE_PACKAGES="torch,torchvision,torchaudio"
    CORE_PACKAGES="${CORE_PACKAGES_ARG:-$DEFAULT_CORE_PACKAGES}"
    
    # 解析核心包列表
    IFS=',' read -ra CORE_PACKAGE_ARRAY <<< "$CORE_PACKAGES"
    PRIMARY_CORE_PACKAGE="${CORE_PACKAGE_ARRAY[0]}"
    
    info "🛡️ 核心包配置:"
    info "   主核心包: $PRIMARY_CORE_PACKAGE"
    if [ ${#CORE_PACKAGE_ARRAY[@]} -gt 1 ]; then
        info "   相关核心包: ${CORE_PACKAGE_ARRAY[*]:1}"
    fi
    info "   冲突包: prefigure"
    
    # 🚀 改进:对所有核心包进行保护,不仅仅是主核心包
    info "🔍 检查所有指定的核心包安装状态..."
    
    # 检查每个核心包是否已安装
    ALL_CORE_PACKAGES_INSTALLED=true
    
    # 🚀 改进:完全使用Python检查,兼容受限环境(无需grep/sed/cut等外部命令)
    torch_check_result=$(python -c "
    try:
        import subprocess
        import sys
        
        # 检查torch包
        result = subprocess.run([sys.executable, '-m', 'pip', 'show', 'torch'], 
                              capture_output=True, text=True, timeout=10)
        if result.returncode == 0:
            version = None
            for line in result.stdout.split('\n'):
                if line.startswith('Version:'):
                    version = line.split(':', 1)[1].strip()
                    break
            
            if version:
                print(f'TORCH_VERSION:{version}')
                if '2.8.0' in version and ('cu' in version or '+cu' in version):
                    print('STATUS:2.8.0_GPU_FOUND')
                elif 'cu' in version or '+cu' in version:
                    print('STATUS:OTHER_GPU_FOUND')
                else:
                    print('STATUS:CPU_VERSION')
            else:
                print('STATUS:NO_VERSION')
        else:
            print('STATUS:NOT_FOUND')
            
        # 同时检查其他核心包
        other_packages = ['torchvision', 'torchaudio']
        missing_packages = []
        for pkg in other_packages:
            pkg_result = subprocess.run([sys.executable, '-m', 'pip', 'show', pkg], 
                                      capture_output=True, text=True, timeout=10)
            if pkg_result.returncode != 0:
                missing_packages.append(pkg)
        
        if missing_packages:
            print(f'MISSING_PACKAGES:{\"|\".join(missing_packages)}')
        else:
            print('ALL_PYTORCH_PACKAGES_FOUND')
            
    except Exception as e:
        print(f'PYTHON_CHECK_FAILED:{e}')
    " 2>/dev/null)
    
    # 使用纯bash字符串处理解析结果
    case "$torch_check_result" in
        *"STATUS:2.8.0_GPU_FOUND"*)
            # 提取版本号
            torch_version=$(echo "$torch_check_result" | while read line; do
                case "$line" in
                    TORCH_VERSION:*) echo "${line#TORCH_VERSION:}" ;;
                esac
            done)
            ok "🎯 检测到 PyTorch 2.8.0 GPU版本: $torch_version,启用强制保护模式"
            ALL_CORE_PACKAGES_INSTALLED=true
            for core_pkg in "${CORE_PACKAGE_ARRAY[@]}"; do
                ok "✅ $core_pkg - 强制保护模式,跳过重复安装"
            done
            ;;
        *"STATUS:OTHER_GPU_FOUND"*)
            torch_version=$(echo "$torch_check_result" | while read line; do
                case "$line" in
                    TORCH_VERSION:*) echo "${line#TORCH_VERSION:}" ;;
                esac
            done)
            ok "🎯 检测到 PyTorch GPU版本: $torch_version,启用强制保护模式"
            ALL_CORE_PACKAGES_INSTALLED=true
            for core_pkg in "${CORE_PACKAGE_ARRAY[@]}"; do
                ok "✅ $core_pkg - 强制保护模式,跳过重复安装"
            done
            ;;
        *"PYTHON_CHECK_FAILED"*|*"STATUS:NOT_FOUND"*)
            # 环境检查失败或torch未安装,提供手动安装指导
            warn "⚠️ 环境检查失败或PyTorch未安装"
            echo ""
            error "💥 建议手动安装以下包:"
            echo ""
            echo "🔧 复制以下命令进行手动安装:"
            echo ""
            echo "# PyTorch GPU版本(推荐)"
            echo "pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128"
            echo ""
            echo "# 或者CPU版本"  
            echo "pip install torch torchvision torchaudio"
            echo ""
            echo "# 其他常用包"
            echo "pip install transformers diffusers opencv-python pillow numpy pandas matplotlib"
            echo ""
            echo "🔄 安装完成后,请重新运行脚本"
            echo ""
            read -p "⚠️  是否继续尝试自动安装?(y/N): " continue_auto
            if [[ ! "$continue_auto" =~ ^[Yy]$ ]]; then
                exit 1
            fi
            ALL_CORE_PACKAGES_INSTALLED=false
            ;;
        *"STATUS:CPU_VERSION"*)
            warn "⚠️ 检测到PyTorch CPU版本,建议升级到GPU版本"
            ALL_CORE_PACKAGES_INSTALLED=false
            ;;
        *)
            # 未知状态,进入常规检查
            ALL_CORE_PACKAGES_INSTALLED=false
            ;;
    esac
    
    # 如果强制保护模式未激活,执行常规检查
    if [ "$ALL_CORE_PACKAGES_INSTALLED" != true ]; then
        # 常规检查流程
        for core_pkg in "${CORE_PACKAGE_ARRAY[@]}"; do
            echo "🔍 正在检查核心包: $core_pkg" >&2
            if check_package_installed "$core_pkg"; then
                ok "✅ $core_pkg - 已正确安装"
                echo "✅ 核心包 $core_pkg 检查通过" >&2
            else
                warn "📦 $core_pkg - 需要安装"
                echo "❌ 核心包 $core_pkg 检查失败" >&2
                ALL_CORE_PACKAGES_INSTALLED=false
            fi
        done
    fi
    
    echo "🎯 最终状态: ALL_CORE_PACKAGES_INSTALLED=$ALL_CORE_PACKAGES_INSTALLED" >&2
    
    if [ "$ALL_CORE_PACKAGES_INSTALLED" = true ]; then
        ok "🎉 所有指定的核心包都已安装,跳过核心包保护流程"
    else
        # 只有在需要时才进行保护性安装
        info "🛡️ 开始核心包保护性安装流程..."
        
        # 确保再安装了prefigure之后安装的是指定的核心包版本
        if ! ensure_core_package_installed "$PRIMARY_CORE_PACKAGE" "prefigure"; then
            trace_error "核心包保护性安装流程失败" "ensure_core_package_installed 函数返回非零退出码"
            error "核心包 $PRIMARY_CORE_PACKAGE 安装失败,无法继续"
        fi
    fi
    
    # -----------------------------
    # 6.5. 🎯 核心大型包专项安装阶段
    # -----------------------------
    
    # 🎯 核心大型包安装函数:专门处理需要大量下载的包
    install_essential_large_packages() {
        info "🎯 开始核心大型包专项安装阶段..."
        
        echo "🔍 调试: ALL_CORE_PACKAGES_INSTALLED=${ALL_CORE_PACKAGES_INSTALLED:-未设置}" >&2
        
        # 🚀 如果前面已经确认所有核心包都安装了,直接跳过
        if [ "${ALL_CORE_PACKAGES_INSTALLED:-false}" = true ]; then
            ok "🎉 前面已确认所有核心包都已安装,跳过大型包安装阶段"
            echo "✅ 大型包安装阶段成功跳过" >&2
            return 0
        fi
        
        echo "⚠️ 继续执行大型包安装流程" >&2
        
        # �️ 创建已安装核心包保护列表 - 防止依赖重装
        local PROTECTED_CORE_PACKAGES=()
        if [ -n "${CORE_PACKAGE_ARRAY:-}" ] && [ ${#CORE_PACKAGE_ARRAY[@]} -gt 0 ]; then
            for core_pkg in "${CORE_PACKAGE_ARRAY[@]}"; do
                if check_package_installed "$core_pkg"; then
                    PROTECTED_CORE_PACKAGES+=("$core_pkg")
                    info "🛡️ 保护已安装核心包: $core_pkg"
                fi
            done
        fi
        
        # �🚀 智能使用 CLI 指定的核心包,而不是硬编码列表
        local ESSENTIAL_LARGE_PACKAGES=()
        
        # 如果有 CLI 指定的核心包,优先使用
        if [ -n "${CORE_PACKAGE_ARRAY:-}" ] && [ ${#CORE_PACKAGE_ARRAY[@]} -gt 0 ]; then
            ESSENTIAL_LARGE_PACKAGES=("${CORE_PACKAGE_ARRAY[@]}")
            info "📋 使用 CLI 指定的核心包: ${ESSENTIAL_LARGE_PACKAGES[*]}"
        else
            # 回退到默认的大型包列表
            ESSENTIAL_LARGE_PACKAGES=(
                "torch" "torchvision" "torchaudio"
                "tensorflow" "transformers" "diffusers"
                "opencv-python" "pillow"
            )
            info "📋 使用默认大型包列表"
        fi
        
        # 检查是否有任何核心包需要安装
        local large_packages_needed=()
        
        # 🛡️ 应用保护过滤:从安装列表中移除已保护的核心包
        local filtered_packages=()
        readarray -t filtered_packages < <(filter_installed_packages "${ESSENTIAL_LARGE_PACKAGES[@]}")
        
        # 进一步过滤:移除已保护的核心包,防止依赖冲突重装
        for pkg in "${filtered_packages[@]}"; do
            local is_protected=false
            for protected_pkg in "${PROTECTED_CORE_PACKAGES[@]}"; do
                if [ "$pkg" = "$protected_pkg" ]; then
                    info "🛡️ 跳过已保护核心包: $pkg (防止依赖重装)"
                    is_protected=true
                    break
                fi
            done
            if [ "$is_protected" = false ]; then
                large_packages_needed+=("$pkg")
            fi
        done
        
        if [ ${#large_packages_needed[@]} -eq 0 ]; then
            ok "🎉 所有核心大型包都已安装,跳过专项安装阶段"
            return 0
        fi
        
        # 给用户明确的提示
        info "📋 检测到需要安装的核心大型包 (${#large_packages_needed[@]}个):"
        for pkg in "${large_packages_needed[@]}"; do
            case "$pkg" in
                torch|torchvision|torchaudio)
                    info "   🔥 $pkg - PyTorch生态系统 (~200-500MB)"
                    ;;
                tensorflow)
                    info "   🧠 $pkg - TensorFlow框架 (~400MB)"
                    ;;
                transformers)
                    info "   🤗 $pkg - Hugging Face模型库 (~100MB)"
                    ;;
                diffusers)
                    info "   🎨 $pkg - 扩散模型库 (~50MB)"
                    ;;
                opencv-python)
                    info "   👁️  $pkg - 计算机视觉库 (~90MB)"
                    ;;
                *)
                    info "   📦 $pkg - 核心依赖包"
                    ;;
            esac
        done
        
        info "⚠️  注意: 这些包下载量较大,预计总下载量: 500MB-2GB"
        info "🌐 将使用最快的镜像源进行下载"
        info "⏰ 预计耗时: 2-15分钟 (取决于网络速度)"
        info "💡 下载过程中会显示详细的进度和速度信息"
        echo ""
        
        # 让用户有心理准备
        read -t 10 -p "⏳ 10秒后开始下载,按回车立即开始,或按Ctrl+C取消: " || true
        echo ""
        
        # 分批安装大型包 (避免内存压力)
        local batch_size=2
        local total_packages=${#large_packages_needed[@]}
        local current_batch=1
        local total_batches=$(( (total_packages + batch_size - 1) / batch_size ))
        
        for ((i=0; i /dev/null; then
            has_gpu=true
            info "✅ 检测到 GPU 环境"
        else
            info "ℹ️  未检测到 GPU 环境,跳过 GPU 版本验证"
            return 0
        fi
        
        # 检查 PyTorch 是否支持 CUDA
        local cuda_check_output=""
        cuda_check_output=$(python -c "
    import torch
    print(f'PyTorch版本: {torch.__version__}')
    print(f'CUDA可用: {torch.cuda.is_available()}')
    if torch.cuda.is_available():
        print(f'CUDA版本: {torch.version.cuda}')
        print(f'GPU设备: {torch.cuda.get_device_name(0)}')
        print('GPU_SUPPORTED')
    elif '+cu' in torch.__version__ or 'cuda' in torch.__version__.lower():
        print('GPU版本已安装但CUDA不可用(可能是驱动问题)')
        print('GPU_VERSION_INSTALLED')
    else:
        print('CPU_ONLY')
    " 2>&1)
        
        local cuda_check_exit_code=$?
        
        if [ $cuda_check_exit_code -ne 0 ]; then
            trace_error "PyTorch 导入失败" "$cuda_check_output" "$cuda_check_exit_code"
            error "❌ PyTorch 导入失败,请检查安装"
            return 1
        fi
        
        echo "$cuda_check_output"
        
        # 检查是否支持 GPU 或已安装 GPU 版本
        if echo "$cuda_check_output" | grep -q "GPU_SUPPORTED"; then
            ok "✅ PyTorch GPU 版本验证成功"
            return 0
        elif echo "$cuda_check_output" | grep -q "GPU_VERSION_INSTALLED"; then
            warn "⚠️  PyTorch GPU版本已安装但CUDA不可用,可能是驱动问题"
            ok "✅ PyTorch GPU 版本已正确安装,跳过重装"
            return 0
        elif echo "$cuda_check_output" | grep -q "CPU_ONLY"; then
            warn "⚠️  检测到 CPU 版本的 PyTorch,需要重新安装 GPU 版本"
            
            # 强制重新安装 GPU 版本
            info "🔄 正在重新安装 GPU 版本的 PyTorch..."
            
            # 先卸载 CPU 版本
            info "📥 卸载当前版本..."
            pip uninstall torch torchvision torchaudio -y >/dev/null 2>&1 || true
            
            # 重新安装 GPU 版本
            if install_torch_gpu; then
                # 再次验证
                local recheck_output=""
                recheck_output=$(python -c "
    import torch
    print(f'重新安装后 - PyTorch版本: {torch.__version__}')
    print(f'CUDA可用: {torch.cuda.is_available()}')
    if torch.cuda.is_available():
        print(f'GPU设备: {torch.cuda.get_device_name(0)}')
        print('RECHECK_GPU_OK')
    else:
        print('RECHECK_STILL_CPU')
    " 2>&1)
                
                if echo "$recheck_output" | grep -q "RECHECK_GPU_OK"; then
                    ok "✅ GPU 版本 PyTorch 重新安装成功"
                    echo "$recheck_output"
                    return 0
                else
                    trace_error "PyTorch GPU 重新安装验证失败" "$recheck_output"
                    error "❌ 重新安装后仍然不支持 GPU,请检查 CUDA 环境"
                    return 1
                fi
            else
                error "❌ GPU 版本 PyTorch 重新安装失败"
                return 1
            fi
        else
            trace_error "PyTorch GPU 验证异常" "$cuda_check_output"
            error "❌ PyTorch GPU 验证结果异常"
            return 1
        fi
    }
    
    # 执行最终验证
    if ! final_gpu_verification; then
        error "❌ PyTorch GPU 最终验证失败"
    fi
    
    info "🎉 环境配置完成!"
    
    # -----------------------------
    # 9. ✅ 最终成功提示(终端彩色 + 日志纯文本)
    # -----------------------------
    
    # 调用时先获取
    get_activate_cmd "$ENV_NAME" "$ENV_PATH"
    
    log_success "$PLATFORM" "$ENV_NAME" "$LOG_FILE" "$WORKSPACE" "$ACTIVATE_CMD" "$DETECTED_ENV_TYPE"
    
    
    ;>

    20250905 0445 ...

    立即注册
    更新于:2025-09-05 04:45:23
    相关内容

    Shadowsocks服务原理

    灵魂 (汉语词语)(英文:soul)

    为何 shadowsocks 弃用一次性验证 (OTA)

    console.log() %c 加入样式中 color 颜色设置无效的问题。

    小技巧:apache启动错误 AH00072: make_sock: could not bind to address ...

    推荐内容

    怎样使用V2Ray代理和SSTap玩如魔兽世界/绝地求生/LOL台服/战地3/黑色沙漠/彩...

    sstap游戏代理教程 从此玩如魔兽世界/绝地求生/LOL台服/战地3/黑色沙漠/彩虹六...

    BT磁力搜索网站汇总和找不到的资源

    什么是磁力链接,您如何使用?

    Z-Library:全球最大的数字图书馆/含打不开的解决方案/镜像

    使用V2Ray的mKCP协议加速游戏

    v2rayN已停止工作

    【车险课堂】什么是无赔款优待系数ncd,你“造”吗?