Stories

Detail Return Return

AI 寫文章系列——Ubuntu 24.04 pipx install 解決 ModuleNotFoundError 問題 - Stories Detail

概述

自從轉 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 Avatar huandanshendeshoushudao Avatar beibiaobaidehaigui Avatar jianghushinian Avatar meiyoufujideyidongdianyuan Avatar javalover Avatar wangqingsheng Avatar huaming Avatar nogeek Avatar mougeyewan Avatar aihejiudejiqiren_bjjawt Avatar 5e4jkgqh Avatar
Favorites 17 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.