動態

詳情 返回 返回

AI 寫文章系列——Ubuntu 24.04 pipx install 解決 ModuleNotFoundError 問題 - 動態 詳情

概述

自從轉 Go 之後,好久沒寫 Python 了。最近在 Ubuntu 24.04 中使用 pipx 安裝了一個工具之後,運行報依賴錯誤。把上下文餵給 DeepSeek 之後,最終解決了問題。

我讓 DeepSeek 回顧問答的上下文,整理了一篇文章出來——不過相比上一篇,這次我人工介入修改的內容多得多。


問題提出

最近需要扣一個圖,把我的證件照背景顏色換一換。搜了一下,在 Github 上找到一個高 star 的項目 rembg 的圖片背景去除工具,用 pipx install rembg 安裝後運行時,卻遇到了 ModuleNotFoundError: No module named 'onnxruntime' 的錯誤。這明顯是包依賴問題。奇怪了,看起來 pipx 沒有 pip 那麼聰明?

為什麼用 pipx 而不是 pip?

在 Ubuntu 24.04 中,系統默認安裝了 Python 3.12,所以我就不用費心去自己通過源碼安裝。但為了避免污染全局環境,官方不推薦使用 pip,而是 pipx 來管理命令行工具。原因如下:

  • 系統 Python 的自我保護: Ubuntu 的系統工具(如 apt)依賴 Python 環境,直接使用 pip 安裝全局包可能導致依賴衝突,甚至破壞系統功能。
  • 隔離性需求: pipx 會為每個包創建獨立的虛擬環境,避免包之間的依賴衝突。例如,安裝 rembg 時,其依賴的 numpy 版本不會影響其他工具。
  • 命令行工具的天然適配: pipx 會自動將包的可執行文件鏈接到 ~/.local/bin,無需手動配置環境變量,適合管理 rembg 這類 CLI 工具。

現象

安裝 rembg 看似成功,但運行時直接報錯:

$ rembg i input.png output.png
Traceback (most recent call last):
  File "/root/.local/bin/rembg", line 5, in <module>
    from rembg.cli import main
  File "/root/.local/share/pipx/venvs/rembg/lib/python3.12/site-packages/rembg/__init__.py", line 5, in <module>
    from .bg import remove
  File "/root/.local/share/pipx/venvs/rembg/lib/python3.12/site-packages/rembg/bg.py", line 7, in <module>
    import onnxruntime as ort
ModuleNotFoundError: No module named 'onnxruntime'

關鍵信息: rembg 運行時找不到 onnxruntime 模塊。


解決方案

找 DeepSeek 問,説實話,DeepSeek 對問題的原因的解釋並不能讓我滿意,它給出的解決方法也有好幾條。經過 7 輪問答,我最終挑選了一個可行的方案。

被驗證不可行的方案

  1. 強制重裝 rembg

嘗試卸載後強制重裝,但問題依舊:

pipx uninstall rembg
pipx install rembg --force
  1. 全局安裝 onnxruntime

直接運行 pipx install onnxruntime,這個方法可以,但是依賴又不止這一個,一個個安裝挺麻煩的。此外 pipx install 會為 onnxruntime 創建新虛擬環境,而非注入到 rembg 的環境,推薦用 pipx inject 的模式。


關鍵操作: pipx inject vs pipx install

1. pipx inject 的作用

  • 精準注入依賴: 將指定包安裝到某個應用的虛擬環境中。
  • 解決依賴隔離問題: 例如,為 rembg 單獨安裝 onnxruntime:
pipx inject rembg onnxruntime

最終解決方案: 自動化腳本

  1. 自動捕獲缺失依賴: 從錯誤日誌中提取 ModuleNotFoundError 提示的模塊名。
  2. 循環安裝與重試: 直到命令成功或達到最大重試次數。
#!/bin/bash
# auto_fix_pipx_deps_loop_fixed.sh

# 配置參數
PACKAGE="rembg"  # 替換為你的包名
COMMAND="rembg"  # 替換為需要執行的命令
MAX_RETRY=20     # 最大重試次數,防止無限循環

# 臨時日誌文件
LOG="/tmp/pipx_error.log"

# 初始化計數器
retry_count=0
success=0

while [ $retry_count -lt $MAX_RETRY ] && [ $success -eq 0 ]; do
    # 清理舊日誌
    rm -f "$LOG"

    # 運行命令並捕獲輸出,同時記錄原始退出狀態碼
    echo "嘗試運行命令 (第 $((retry_count+1)) 次)..."
    $COMMAND 2>&1 | tee "$LOG"
    original_exit_code=${PIPESTATUS[0]}  # 獲取原命令的退出狀態碼

    # 檢查命令是否成功
    if [ $original_exit_code -eq 0 ]; then
        echo "命令執行成功!"
        success=1
        break
    else
        echo "命令執行失敗,退出碼: $original_exit_code"
    fi

    # 提取缺失的模塊名(去重)
    MISSING_MODULES=$(grep -o "ModuleNotFoundError: No module named '[^']*'" "$LOG" | awk -F"'" '{print $2}' | sort | uniq)

    if [ ! -z "$MISSING_MODULES" ]; then
        echo "檢測到缺失依賴: $MISSING_MODULES"
        for MODULE in $MISSING_MODULES; do
            echo "正在安裝: $MODULE"
            pipx inject "$PACKAGE" "$MODULE"
            if [ $? -ne 0 ]; then
                echo "安裝依賴 $MODULE 失敗,請手動處理。"
                exit 1
            fi
        done
    else
        echo "未檢測到缺失的 Python 依賴。請檢查以下可能原因:"
        echo "1. 系統級依賴未安裝(如 libgomp1)"
        echo "2. 動態導入的依賴未在代碼中顯式聲明"
        echo "3. 其他運行時錯誤(查看日誌: $LOG)"
        break
    fi

    # 增加重試計數
    retry_count=$((retry_count+1))
done

# 最終狀態檢查
if [ $success -eq 0 ]; then
    echo "已達到最大重試次數 ($MAX_RETRY),問題仍未解決。請手動檢查日誌: $LOG"
    exit 1
else
    exit 0
fi

腳本運行效果

執行效果類似於這樣子的:

嘗試運行命令 (第 1 次)...
Traceback (most recent call last):
  File "/root/.local/bin/rembg", line 5, in <module>
    from rembg.cli import main
ModuleNotFoundError: No module named 'onnxruntime'
檢測到缺失依賴: onnxruntime
正在安裝: onnxruntime
  injected package onnxruntime into venv rembg

嘗試運行命令 (第 2 次)...
Traceback (most recent call last):
  File "/root/.local/bin/rembg", line 5, in <module>
    from rembg.cli import main
  File "/root/.local/share/pipx/venvs/rembg/lib/python3.12/site-packages/rembg/cli.py", line 4, in <module>
    from .commands import command_functions
  File "/root/.local/share/pipx/venvs/rembg/lib/python3.12/site-packages/rembg/commands/__init__.py", line 7, in <module>
    from .s_command import s_command
  File "/root/.local/share/pipx/venvs/rembg/lib/python3.12/site-packages/rembg/commands/s_command.py", line 6, in <module>
    import aiohttp
ModuleNotFoundError: No module named 'aiohttp'
命令執行失敗,退出碼: 1
檢測到缺失依賴: aiohttp
正在安裝: aiohttp
  injected package aiohttp into venv rembg

......

安裝過程中會出現一些失敗的情況,一般都是超時等網絡問題。解決網絡錯誤之後再跑這個腳本就行了


本文章採用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。

原作者: amc,歡迎轉載,但請註明出處。

原文標題: 《AI 寫文章系列——Ubuntu 24.04 pipx install 解決 ModuleNotFoundError 問題》

發佈日期: 2025-03-29

原文鏈接: https://cloud.tencent.com/developer/article/2508854。

CC BY-NC-SA 4.0 DEED.png

user avatar congrongdehanbaobao 頭像 huandanshendeshoushudao 頭像 beibiaobaidehaigui 頭像 jianghushinian 頭像 meiyoufujideyidongdianyuan 頭像 javalover 頭像 wangqingsheng 頭像 huaming 頭像 nogeek 頭像 mougeyewan 頭像 aihejiudejiqiren_bjjawt 頭像 5e4jkgqh 頭像
點贊 17 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.