| name | setup-env |
| description | Set up Python/CUDA deep learning environments on Linux servers. Use this skill when the user needs to install conda environments, pip packages, PyTorch, flash-attn, clone GitHub repos, or download HuggingFace models — especially in restricted network environments (China mainland servers) where mirrors are needed. |
Setup CUDA Environment
Guide for configuring Python/CUDA deep learning environments on Linux servers. Handles mirror selection, disk space, and common pitfalls from experience.
Step 1: Probe Network Connectivity First
Always test before assuming any mirror works. Run this block and record which services respond:
echo "=== pip mirrors ==="
for m in \
"https://mirrors.aliyun.com/pypi/simple" \
"https://pypi.tuna.tsinghua.edu.cn/simple" \
"https://mirrors.ustc.edu.cn/pypi/simple"; do
code=$(curl -sk --connect-timeout 5 -o /dev/null -w "%{http_code}" "$m")
echo "$code $m"
done
echo "=== GitHub mirrors ==="
for m in \
"https://bgithub.xyz" \
"https://gitclone.com" \
"https://mirror.ghproxy.com"; do
code=$(curl -sk --connect-timeout 5 -o /dev/null -w "%{http_code}" "$m")
echo "$code $m"
done
echo "=== HuggingFace mirror ==="
curl -sk --connect-timeout 5 -o /dev/null -w "%{http_code}" "https://hf-mirror.com" && echo " https://hf-mirror.com"
echo "=== Disk space ==="
df -h / /tmp
HTTP 200/301/302 = usable. 000/5xx = skip it. Pick the first usable one from each category.
Step 2: Create conda Environment
Do not specify -c conda-forge or other channels — they may be unreachable. The default channel is enough to create a clean Python environment:
conda create -n <env_name> python=3.10 -y
Critical: never use conda run -n <env> pip — it can silently resolve to the system pip instead of the env's pip. Always use the absolute path:
CONDA_PREFIX=$(conda env list | grep "^<env_name>[[:space:]]" | awk '{print $NF}')
PY="${CONDA_PREFIX}/bin/python"
PIP="${CONDA_PREFIX}/bin/pip"
$PY --version
$PIP --version
Step 3: Install PyTorch
Use the official PyTorch wheel index (not PyPI) to get the CUDA build:
$PIP install torch torchvision torchaudio \
--index-url https://download.pytorch.org/whl/cu124 \
--no-cache-dir
$PY -c "import torch; print(torch.__version__, torch.cuda.is_available())"
Replace cu124 with cu118/cu121 etc. to match the server's CUDA toolkit version.
Step 4: Install pip Packages
Use the usable mirror from Step 1:
$PIP install -r requirements.txt \
-i https://mirrors.aliyun.com/pypi/simple \
--no-cache-dir
Check disk space before large installs — container / partitions are often 20–30 GB and fill up fast:
df -h /
du -sh /tmp
If /tmp is nearly full, set TMPDIR to a large disk (e.g. NVMe mount) before installing.
Step 5: Install flash-attn
flash-attn requires compilation. Several pitfalls apply:
$PY -c "import flash_attn; print(flash_attn.__version__)" 2>/dev/null && echo "skip"
If not installed:
GPU_ARCH=$($PY -c "import torch; cc=torch.cuda.get_device_capability(); print(f'{cc[0]}.{cc[1]}')" 2>/dev/null || echo "8.9")
LARGE_TMP="/path/to/large/disk/tmp_flash"
mkdir -p "$LARGE_TMP"
TMPDIR="$LARGE_TMP" \
TORCH_CUDA_ARCH_LIST="$GPU_ARCH" \
FLASH_ATTENTION_FORCE_BUILD=TRUE \
MAX_JOBS=4 \
$PIP install flash-attn --no-build-isolation --no-cache-dir
rm -rf "$LARGE_TMP"
Key env vars:
FLASH_ATTENTION_FORCE_BUILD=TRUE — skip downloading prebuilt wheels from GitHub Releases (often unreachable), go straight to local compilation
TORCH_CUDA_ARCH_LIST — only compile for this server's GPU architecture; without it, all architectures are compiled (73+ kernels vs ~15), making compilation ~5x slower
TMPDIR — redirect intermediate .cu compilation files away from a small /tmp
MAX_JOBS=4 — cap parallel compile workers to avoid OOM
Step 6: Clone GitHub Repos
Do not use git config --global url.<mirror>.insteadOf — different mirrors use incompatible URL formats, and insteadOf rules compose incorrectly (e.g. gitclone.com needs https://gitclone.com/github.com/<user>/<repo>, not <mirror>https://github.com/<user>/<repo>).
Instead, clear any old rules and construct the full mirror URL explicitly:
git config --global --unset "url.https://mirror.ghproxy.com/https://github.com/.insteadOf" 2>/dev/null || true
git config --global --unset "url.https://gitclone.com/github.com/.insteadOf" 2>/dev/null || true
git config --global --unset "url.https://bgithub.xyz/.insteadOf" 2>/dev/null || true
GH_MIRROR="https://bgithub.xyz"
gh_clone() {
local github_url="$1"
local dest="$2"
[ -d "${dest}/.git" ] && { echo "already cloned: $dest"; return 0; }
local clone_url
case "$GH_MIRROR" in
*gitclone.com*)
clone_url="https://gitclone.com/github.com/${github_url#https://github.com/}"
;;
*)
clone_url="${GH_MIRROR}/${github_url#https://github.com/}"
;;
esac
git clone --depth=1 "$clone_url"
}
gh_clone
If a repo clone fails mid-way and leaves a corrupt .git, delete the directory and re-clone — git pull on a corrupt shallow clone will fail.
Step 7: Download HuggingFace Models
export HF_ENDPOINT="https://hf-mirror.com"
huggingface-cli download <org/model-id> \
--local-dir ./pretrained_models/<name> \
--local-dir-use-symlinks False \
--resume-download
import os
os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
from huggingface_hub import snapshot_download
snapshot_download(repo_id="<org/model-id>", local_dir="./pretrained_models/<name>")
Large models (30B+ parameters) are 60–120 GB. Check free space before starting, and always use --resume-download so interrupted downloads can continue.
Common Pitfalls
| Symptom | Cause | Fix |
|---|
conda run pip installs to wrong Python | conda run path resolution bug | Use ${CONDA_PREFIX}/bin/pip |
No space left on device during flash-attn | /tmp too small for CUDA compilation | Set TMPDIR to large disk |
| git clone 502 | Mirror down | Try next mirror from probe list |
| git clone URL malformed | Wrong insteadOf format for that mirror | Don't use insteadOf; build URL explicitly |
ModuleNotFoundError after pip install | Installed to system Python, not conda env | Verify which pip or use absolute path |
| flash-attn compile takes 30+ min | All GPU archs compiled by default | Set TORCH_CUDA_ARCH_LIST to current GPU only |
| flash-attn wheel download fails silently | GitHub Releases blocked | Set FLASH_ATTENTION_FORCE_BUILD=TRUE |
pip install -e fails with "not a valid editable" | Cloned to wrong directory | Check working directory before clone |