建深度學(xué)習(xí)環(huán)境并 VSCode Codex 遠(yuǎn)程使用:TaoToken 統(tǒng)一 Key 配置骨架)
1. 為什么要在 Docker 里跑深度學(xué)習(xí)環(huán)境再用 VSCode Codex 遠(yuǎn)程寫代碼如果你手頭有一臺(tái)帶 GPU 的服務(wù)器或者本地機(jī)器裝了顯卡但不想把系統(tǒng)環(huán)境搞亂把深度學(xué)習(xí)環(huán)境塞進(jìn) Docker 容器、再用 VSCode 遠(yuǎn)程連進(jìn)去寫代碼是目前比較省心的做法。核心邏輯很簡(jiǎn)單宿主機(jī)只負(fù)責(zé)顯卡驅(qū)動(dòng)和 Docker 引擎容器里裝 Ubuntu、CUDA、cuDNN、Python、PyTorch 和項(xiàng)目依賴。這樣環(huán)境可復(fù)制、可遷移換機(jī)器時(shí)把 Dockerfile 和 compose 文件帶走就行。但真正落地時(shí)會(huì)遇到幾個(gè)具體問(wèn)題容器里的 Python 解釋器怎么讓 VSCode 認(rèn)到、Codex 插件怎么在容器環(huán)境里調(diào)用模型、API Key 怎么統(tǒng)一管理而不是散落在各個(gè)配置文件里。這篇就圍繞「Docker 創(chuàng)建深度學(xué)習(xí)環(huán)境 VSCode 遠(yuǎn)程連接 Codex 插件接入 TaoToken 統(tǒng)一 Key」這條鏈路給出可以直接復(fù)制的 Dockerfile、docker-compose.yml、devcontainer.json 和 Codex settings.json 配置并附上容器內(nèi) curl 驗(yàn)證和遠(yuǎn)程補(bǔ)全測(cè)試的完整動(dòng)作。適合誰(shuí)看手里有 GPU 機(jī)器、想用容器隔離深度學(xué)習(xí)環(huán)境、同時(shí)希望用 Codex 做代碼補(bǔ)全和輔助開發(fā)的開發(fā)者。不需要你已經(jīng)是 Docker 老手但需要你能在終端里執(zhí)行命令、能編輯配置文件。2. TaoToken 前置準(zhǔn)備統(tǒng)一 Key 與 API 通道在講 Docker 和 VSCode 配置之前先把模型調(diào)用這條線理清楚。Codex 插件在容器里運(yùn)行時(shí)需要訪問(wèn)一個(gè)兼容 OpenAI 接口的 API 通道。TaoToken 提供的就是這個(gè)統(tǒng)一入口你拿到一個(gè) Key配置好 base_urlCodex 就能通過(guò)它調(diào)用模型。你需要提前做兩件事第一注冊(cè)并獲取 API Key。訪問(wèn) TaoToken 官網(wǎng) https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 完成注冊(cè)然后在控制臺(tái)里創(chuàng)建一個(gè) API Key。這個(gè) Key 后面會(huì)寫進(jìn) Codex 的配置文件里。第二確認(rèn) API 通道地址。TaoToken 的 API 端點(diǎn)是 https://taotoken.net/api這個(gè)地址不加 UTM 參數(shù)直接作為 base_url 使用。Codex 插件和 CLI 都支持自定義 base_url所以你可以把請(qǐng)求指向這個(gè)通道。注意API Key 不要寫進(jìn) Dockerfile也不要用ENV指令固化到鏡像里。鏡像層是可以被導(dǎo)出的Key 泄露風(fēng)險(xiǎn)很高。正確做法是通過(guò)環(huán)境變量注入或者放在宿主機(jī)的.env文件里由 docker-compose 讀取后傳給容器。如果你還沒(méi)創(chuàng)建 Key可以先打開 API Keys 管理頁(yè)面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。創(chuàng)建后復(fù)制保存后面配置 Codex 時(shí)直接粘貼。3. Dockerfile 與 docker-compose 骨架容器內(nèi)深度學(xué)習(xí)環(huán)境3.1 基礎(chǔ)鏡像選擇不要用裸的ubuntu:22.04從頭裝 CUDA直接用 NVIDIA 官方帶 CUDA 和 cuDNN 的鏡像。推薦FROM nvidia/cuda:12.8.1-cudnn-devel-ubuntu22.04這個(gè)鏡像本質(zhì)是 Ubuntu 22.04但已經(jīng)帶好了 CUDA 12.8 和 cuDNN 開發(fā)環(huán)境適合 PyTorch、CUDA 擴(kuò)展編譯、YOLO、OpenCV 等場(chǎng)景。如果你的宿主機(jī)nvidia-smi顯示的 CUDA Version 低于 12.8就把基礎(chǔ)鏡像和 PyTorch 安裝源都降到 cu126。3.2 Dockerfile 完整骨架在項(xiàng)目目錄dl-docker/Dockerfile寫入FROM nvidia/cuda:12.8.1-cudnn-devel-ubuntu22.04 ARG USERNAMEdev ARG USER_UID1000 ARG USER_GID1000 ARG PYTHON_VERSION3.11 ENV DEBIAN_FRONTENDnoninteractive ENV TZAsia/Shanghai ENV CONDA_DIR/opt/conda ENV PATH/opt/conda/bin:$PATH ENV PIP_CACHE_DIR/cache/pip ENV HF_HOME/cache/huggingface ENV TRANSFORMERS_CACHE/cache/huggingface ENV TORCH_HOME/cache/torch ENV PYTHONUNBUFFERED1 ENV PYTHONDONTWRITEBYTECODE1 RUN apt-get update apt-get install -y --no-install-recommends \ sudo git git-lfs wget curl vim nano tmux htop tree unzip zip \ ca-certificates build-essential cmake ninja-build pkg-config \ ffmpeg libgl1 libglib2.0-0 libsm6 libxext6 libxrender-dev libgomp1 \ openssh-client nodejs npm \ rm -rf /var/lib/apt/lists/* RUN groupadd --gid ${USER_GID} ${USERNAME} \ useradd --uid ${USER_UID} --gid ${USER_GID} -m ${USERNAME} -s /bin/bash \ echo ${USERNAME} ALL(ALL) NOPASSWD:ALL /etc/sudoers.d/${USERNAME} \ chmod 0440 /etc/sudoers.d/${USERNAME} RUN wget -q https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O /tmp/miniconda.sh \ bash /tmp/miniconda.sh -b -p ${CONDA_DIR} \ rm /tmp/miniconda.sh \ ${CONDA_DIR}/bin/conda clean -afy RUN conda create -y -n dl python${PYTHON_VERSION} \ conda clean -afy SHELL [conda, run, -n, dl, /bin/bash, -c] RUN pip install --upgrade pip setuptools wheel \ pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128 COPY requirements.txt /tmp/requirements.txt RUN pip install -r /tmp/requirements.txt \ rm /tmp/requirements.txt RUN npm install -g openai/codex || true RUN echo source /opt/conda/etc/profile.d/conda.sh /home/${USERNAME}/.bashrc \ echo conda activate dl /home/${USERNAME}/.bashrc \ echo cd /workspace /home/${USERNAME}/.bashrc RUN mkdir -p /workspace /data /outputs /cache \ chown -R ${USERNAME}:${USERNAME} /workspace /data /outputs /cache /home/${USERNAME} USER ${USERNAME} WORKDIR /workspace CMD [/bin/bash]關(guān)鍵點(diǎn)說(shuō)明創(chuàng)建了非 root 用戶dev避免 VSCode 和 Codex 寫出的文件在宿主機(jī)上變成 root 權(quán)限conda 環(huán)境命名為dlPython 3.11PyTorch 用 cu128 源安裝Codex CLI 通過(guò) npm 全局安裝容器終端里可以直接用。3.3 requirements.txtnumpy pandas scipy scikit-learn matplotlib seaborn opencv-python pillow tqdm rich jupyterlab notebook ipywidgets tensorboard wandb mlflow einops timm albumentations ultralytics transformers datasets accelerate peft sentencepiece protobuf safetensors huggingface_hub openpyxl pyyaml python-dotenv pytest black isort ruff mypy做 CV 就保留 ultralytics、opencv-python、albumentations做大模型就重點(diǎn)保留 transformers、datasets、accelerate、peft。3.4 docker-compose.ymlservices: dl-ubuntu: build: context: . dockerfile: Dockerfile args: USERNAME: dev USER_UID: 1000 USER_GID: 1000 PYTHON_VERSION: 3.11 image: dl-ubuntu-cuda128:latest container_name: dl-ubuntu runtime: nvidia environment: NVIDIA_VISIBLE_DEVICES: all NVIDIA_DRIVER_CAPABILITIES: compute,utility PYTHONUNBUFFERED: 1 HF_HOME: /cache/huggingface TRANSFORMERS_CACHE: /cache/huggingface TORCH_HOME: /cache/torch PIP_CACHE_DIR: /cache/pip TZ: Asia/Shanghai volumes: - ./workspace:/workspace - ./data:/data - ./outputs:/outputs - ./cache:/cache ports: - 8810:8888 - 6116:6006 - 5010:5000 - 7870:7860 - 8010:8000 shm_size: 16gb ipc: host stdin_open: true tty: true command: /bin/bashshm_size和ipc: host對(duì)多 GPU 訓(xùn)練和 PyTorch DataLoader 很重要能減少共享內(nèi)存不足的報(bào)錯(cuò)。如果你的宿主機(jī) UID/GID 不是 1000先用id -u和id -g查一下把 compose 里的值改掉。4. VSCode 遠(yuǎn)程連接與 Codex 插件配置4.1 連接路徑整體路徑是本地 VSCode → Remote-SSH 連到 GPU 服務(wù)器 → 在服務(wù)器上 Attach 到運(yùn)行中的容器 → 在容器/workspace里寫代碼、跑訓(xùn)練、用 Codex。本地 VSCode 需要裝這些擴(kuò)展Remote - SSH、Dev Containers、Docker、Python、Jupyter、Codex。先Ctrl Shift P執(zhí)行Remote-SSH: Connect to Host...輸入ssh 用戶名服務(wù)器IP連接成功后左下角顯示SSH: 服務(wù)器IP。然后繼續(xù)Ctrl Shift P執(zhí)行Dev Containers: Attach to Running Container...選擇dl-ubuntu容器。VSCode 會(huì)重新打開一個(gè)窗口左下角顯示Dev Container: dl-ubuntu這時(shí)你已經(jīng)進(jìn)入容器環(huán)境。打開/workspace目錄即可開始工作。4.2 devcontainer.json在dl-docker/.devcontainer/devcontainer.json寫入{ name: dl-ubuntu-cuda, dockerComposeFile: ../docker-compose.yml, service: dl-ubuntu, workspaceFolder: /workspace, shutdownAction: none, remoteUser: dev, customizations: { vscode: { settings: { terminal.integrated.defaultProfile.linux: bash, python.defaultInterpreterPath: /opt/conda/envs/dl/bin/python, python.terminal.activateEnvironment: true, files.autoSave: afterDelay, editor.formatOnSave: true }, extensions: [ ms-python.python, ms-python.vscode-pylance, ms-toolsai.jupyter, ms-azuretools.vscode-docker, ms-vscode-remote.remote-containers, openai.chatgpt ] } }, postAttachCommand: python -V nvidia-smi || true }4.3 Codex 插件接入 TaoToken 統(tǒng)一 KeyCodex 插件在 VSCode 里運(yùn)行時(shí)讀取的是用戶級(jí)或項(xiàng)目級(jí)配置文件。用戶級(jí)配置在~/.codex/config.toml項(xiàng)目級(jí)配置在/workspace/.codex/config.toml。CLI 和 IDE 擴(kuò)展共享配置層。在容器內(nèi)創(chuàng)建配置文件mkdir -p ~/.codex cat ~/.codex/config.toml EOF model gpt-5.5 approval_policy on-request sandbox_mode workspace-write [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chat EOF然后在容器用戶環(huán)境里注入 Key。不要寫死在配置文件里用環(huán)境變量echo export TAOTOKEN_API_KEY你的Key ~/.bashrc source ~/.bashrc如果你用的是 VSCode 的 Codex 插件面板它啟動(dòng)的是 extension host 進(jìn)程不一定繼承你當(dāng)前 bash 終端的環(huán)境變量。所以更穩(wěn)的做法是在devcontainer.json的remoteEnv里注入或者在 docker-compose 的environment段里通過(guò).env文件傳入。在 docker-compose.yml 同級(jí)目錄創(chuàng)建.envTAOTOKEN_API_KEY你的Key然后在 compose 的environment段加一行TAOTOKEN_API_KEY: ${TAOTOKEN_API_KEY}這樣容器啟動(dòng)時(shí)環(huán)境變量就已經(jīng)存在Codex 插件進(jìn)程也能讀到。5. 驗(yàn)證請(qǐng)求與遠(yuǎn)程補(bǔ)全測(cè)試5.1 容器內(nèi) curl 驗(yàn)證進(jìn)入容器docker exec -it dl-ubuntu bash先確認(rèn)環(huán)境變量env | grep TAOTOKEN然后用 curl 測(cè)試 API 通道curl -s -o /dev/null -w %{http_code}\n \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ https://taotoken.net/api/v1/models如果返回200說(shuō)明 Key 和通道都正常。返回401說(shuō)明 Key 沒(méi)帶上或無(wú)效返回404檢查 base_url 路徑。5.2 GPU 與 PyTorch 驗(yàn)證python - PY import torch print(torch:, torch.__version__) print(cuda available:, torch.cuda.is_available()) print(cuda version:, torch.version.cuda) print(gpu count:, torch.cuda.device_count()) if torch.cuda.is_available(): print(gpu name:, torch.cuda.get_device_name(0)) x torch.randn(2048, 2048, devicecuda) y x x print(matmul ok:, y.mean().item()) PY看到cuda available: True和矩陣乘法結(jié)果說(shuō)明容器 GPU 環(huán)境沒(méi)問(wèn)題。5.3 Codex 遠(yuǎn)程補(bǔ)全測(cè)試在 VSCode 容器窗口里打開/workspace下的一個(gè) Python 文件寫幾行代碼觸發(fā) Codex 補(bǔ)全。如果補(bǔ)全正常返回說(shuō)明插件已經(jīng)通過(guò) TaoToken 通道調(diào)到了模型。你也可以在容器終端里直接用 Codex CLI 測(cè)試codex 寫一個(gè) PyTorch DataLoader 的例子如果 CLI 能返回結(jié)果但 VSCode 插件面板不行問(wèn)題通常出在插件進(jìn)程沒(méi)有繼承環(huán)境變量。這時(shí)候執(zhí)行Developer: Reload Window重啟擴(kuò)展宿主或者Dev Containers: Reopen in Container重新進(jìn)入容器。6. 本篇常見錯(cuò)誤排查6.1 Codex 插件報(bào) 401 或連接超時(shí)最常見的原因是插件進(jìn)程沒(méi)有拿到TAOTOKEN_API_KEY環(huán)境變量。你只在當(dāng)前終端export是不夠的VSCode 的 extension host 是獨(dú)立進(jìn)程。解決辦法是把 Key 寫進(jìn) docker-compose 的environment段或者寫進(jìn)devcontainer.json的remoteEnv然后重啟容器和 VSCode 窗口。6.2 PyTorch 報(bào) CUDA 不可用先在宿主機(jī)執(zhí)行nvidia-smi確認(rèn)驅(qū)動(dòng)正常再在容器里執(zhí)行nvidia-smi。如果宿主機(jī)有、容器沒(méi)有檢查 docker-compose 里runtime: nvidia和NVIDIA_VISIBLE_DEVICES是否配置正確。另外確認(rèn)沒(méi)有在容器里裝 NVIDIA 驅(qū)動(dòng)驅(qū)動(dòng)屬于宿主機(jī)容器只需要 CUDA runtime 和 PyTorch 的 CUDA wheel。6.3 OpenCV 報(bào) libGL.so.1 找不到Dockerfile 里已經(jīng)裝了libgl1和libglib2.0-0。如果還是報(bào)錯(cuò)檢查是不是在 conda 環(huán)境外運(yùn)行的 Python或者 pip 裝的 opencv 版本和系統(tǒng)庫(kù)不匹配??梢栽谌萜骼飯?zhí)行l(wèi)dd $(python -c import cv2; print(cv2.__file__)) | grep not found看具體缺哪個(gè)庫(kù)。6.4 DataLoader 報(bào) shared memory 不足把 docker-compose 里的shm_size調(diào)大比如16gb同時(shí)保留ipc: host。這兩個(gè)配置對(duì)多進(jìn)程數(shù)據(jù)加載和 NCCL 通信都有幫助。6.5 VSCode 反復(fù)重連或容器內(nèi)終端環(huán)境不對(duì)如果你是通過(guò) Remote-SSH 先連服務(wù)器再 Attach 容器確認(rèn)devcontainer.json里的remoteUser是dev而不是 root。另外shutdownAction: none可以避免 VSCode 斷開時(shí)容器被停掉。如果終端里 conda 環(huán)境沒(méi)自動(dòng)激活檢查.bashrc里的conda activate dl是否寫進(jìn)去了。6.6 API 請(qǐng)求返回 404檢查 base_url 是否寫成了https://taotoken.net/api不要多加/v1或末尾斜杠。Codex 的wire_api設(shè)為chat時(shí)它會(huì)自動(dòng)拼接路徑。如果返回 404先用 curl 直接測(cè)https://taotoken.net/api/v1/models確認(rèn)通道可達(dá)。7. 后續(xù)維護(hù)與擴(kuò)展這套配置跑通之后你真正需要維護(hù)的核心文件就四個(gè)Dockerfile、requirements.txt、docker-compose.yml、.devcontainer/devcontainer.json。環(huán)境變更寫進(jìn) Dockerfile依賴變更寫進(jìn) requirements.txt容器編排變更寫進(jìn) composeVSCode 和 Codex 的接入配置寫進(jìn) devcontainer.json 和 config.toml。如果你后續(xù)要做長(zhǎng)期編碼或 Agent 類任務(wù)可以了解 TaoToken 的 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。如果只是想驗(yàn)證模型對(duì)話效果可以直接用模型對(duì)話頁(yè)面https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。接入文檔在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 控制臺(tái)在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。數(shù)據(jù)集不要復(fù)制進(jìn)鏡像用 volume 掛到/data。模型緩存掛到/cache/huggingface避免每次重建容器重新下載。環(huán)境變更不要用docker commit寫進(jìn) Dockerfile 才能被 Codex 識(shí)別和修改。