RunPod MCP launcher pour entrainement LLM¶
Ce guide documente notre chemin pratique pour piloter RunPod depuis Codex avec MCP, creer un pod GPU, preparer bia-llms, lancer un smoke training, puis observer les logs. Il complete le guide manuel runpod pods setup.
Le cas concret ici est le smoke du modele Qwen/Qwen3-1.7B sur le dataset prive burkimbia/moore-instruct-v1.
La branche projet pour moore-llm-sota est toujours main, et le workflow training la checkout explicitement.
Objectif¶
- Creer un pod training depuis Codex via le MCP RunPod.
- Utiliser VS Code Remote-SSH ou
code-serverpour inspecter le pod. - Installer
bia-llmsetmoore-llm-sota. - Lancer un smoke run court avant tout entrainement complet.
- Rendre visibles W&B, epochs, checkpoints et S3 dans le template.
- Garder des logs exploitables dans
/workspace. - Stopper ou supprimer les pods instables pour eviter les couts inutiles.
Prerequis¶
Variables locales cote machine Codex:
$env:RUNPOD_API_KEY = "<runpod_api_key>"
$env:GITHUB_ACCESS_TOKEN = "<github_token_repo_private>"
$env:HF_TOKEN = "<huggingface_token_dataset_prive>"
$env:WANDB_API_KEY = "<wandb_key>"
Dans l'interface RunPod, il est preferable d'enregistrer les secrets sous ces noms:
GITHUB_ACCESS_TOKEN
HF_TOKEN
WANDB_API_KEY
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION
AWS_ENDPOINT_URL_S3
S3_CHECKPOINT_URI
S3_MODEL_URI
S3_LOG_URI
Important: les secrets enregistres dans l'interface RunPod ne sont pas toujours lisibles directement par MCP. Ils sont utilisables quand ils sont injectes comme variables d'environnement dans un pod ou un template. Ne pas supposer que MCP peut les relire.
Configuration MCP Codex¶
Ajouter les MCP:
codex mcp add runpod-docs --url https://docs.runpod.io/mcp
codex mcp add runpod --env "RUNPOD_API_KEY=$env:RUNPOD_API_KEY" -- npx -y @runpod/mcp-server@latest
Verifier:
Si RunPod renvoie 401, verifier que la config ne contient pas le litteral casse:
Si c'est le cas:
codex mcp remove runpod
codex mcp add runpod --env "RUNPOD_API_KEY=$env:RUNPOD_API_KEY" -- npx -y @runpod/mcp-server@latest
Redemarrer Codex apres modification MCP. Les serveurs MCP sont charges au demarrage de la session.
Creation du pod par MCP¶
Pour un smoke Qwen3-1.7B, demander au MCP un GPU 24 GB minimum. Les meilleurs choix pratiques:
- Debug: local/CPU d'abord, puis GPU 16-24 GB seulement si CUDA doit etre teste. Chercher A4000, A4500, RTX 4000 Ada, RTX 2000 Ada, A5000, L4 ou 3090 selon le prix live.
NVIDIA RTX A5000ouNVIDIA GeForce RTX 4090pour smoke 1.7B apres validation locale.NVIDIA L40,RTX A6000,RTX 6000 Adapour plus de marge et eventuellement un run 4B.
Ne pas utiliser A6000/L40/48 GB pour setup, docs, template edits ou debug scripts. Ces GPUs sont reserves aux full runs approuves ou aux smoke finaux.
Exemple de specification:
templateId: bgqn0opi39
templateName: moore-llm-sota-training-template
cloudType: COMMUNITY ou SECURE selon stock
imageName: runpod/pytorch:2.8.0-py3.11-cuda12.8.1-cudnn-devel-ubuntu22.04
gpuCount: 1
containerDiskInGb: 50
volumeInGb: 50
volumeMountPath: /workspace
ports:
- 8888/http
- 8080/http
- 22/tcp
env:
RUNPOD_INIT_TIMEOUT: "600"
HF_HOME: /workspace/.cache/huggingface
TRANSFORMERS_CACHE: /workspace/.cache/huggingface
XDG_CACHE_HOME: /workspace/.cache
UV_CACHE_DIR: /workspace/.cache/uv
UV_PROJECT_ENVIRONMENT: /workspace/.venv/bia-llms
UV_LINK_MODE: copy
WANDB_PROJECT: moore-llm-sota
GITHUB_ACCESS_TOKEN: "{{ RUNPOD_SECRET_GITHUB_ACCESS_TOKEN }}"
GITHUB_TOKEN: "{{ RUNPOD_SECRET_GITHUB_ACCESS_TOKEN }}"
HF_TOKEN: "{{ RUNPOD_SECRET_HF_TOKEN }}"
WANDB_API_KEY: "{{ RUNPOD_SECRET_WANDB_API_KEY }}"
AWS_ACCESS_KEY_ID: "{{ RUNPOD_SECRET_AWS_ACCESS_KEY_ID }}"
AWS_SECRET_ACCESS_KEY: "{{ RUNPOD_SECRET_AWS_SECRET_ACCESS_KEY }}"
AWS_DEFAULT_REGION: "auto"
AWS_REGION: "auto"
AWS_ENDPOINT_URL_S3: "https://fly.storage.tigris.dev"
S3_CHECKPOINT_URI: "s3://burkimbia-store/moore-llm-sota/checkpoints"
S3_MODEL_URI: "s3://burkimbia-store/moore-llm-sota/models"
S3_LOG_URI: "s3://burkimbia-store/moore-llm-sota/logs"
RUNPOD_S3_SYNC_INTERVAL_SECONDS: "300"
RUNPOD_AUDIT_INTERVAL_SECONDS: "60"
RUNPOD_SKIP_UV_SYNC: "false"
REQUIRE_S3_SYNC: "true"
BIA_LLMS_BRANCH: "moore-multitask-xml"
BIA_LLMS_FALLBACK_BRANCH: "main"
MOORE_BRANCH: "main"
Pour un smoke non officiel sans S3, mettre temporairement REQUIRE_S3_SYNC=false. Pour un full run, garder REQUIRE_S3_SYNC=true.
Le premier uv sync --extra cu128 --all-groups sur volume neuf peut prendre plusieurs minutes, meme avec un petit GPU, parce qu'il telecharge PyTorch, CUDA, xFormers, bitsandbytes et Unsloth. Garder les caches sous /workspace/.cache et l'environnement sous /workspace/.venv/bia-llms. Si une image ou un volume contient deja l'environnement synchronise, mettre RUNPOD_SKIP_UV_SYNC=true; sinon le premier prepare est la phase lente a surveiller et a stopper si elle bloque.
Le stockStatus=Low ne garantit pas que la creation passera. RunPod peut retourner:
create pod: This machine does not have the resources to deploy your pod
create pod: There are no instances currently available
Dans ce cas, changer de GPU ou de cloud type.
Connexion VS Code ou code-server¶
VS Code Remote-SSH est le choix le plus propre pour developper et lancer les commandes longues. Recuperer l'IP et le port TCP exposes, puis:
Dans VS Code:
- Installer
Remote - SSH. Remote-SSH: Connect to Host.- Ouvrir
/workspace.
code-server est utile comme fallback navigateur. Exposer 8080/http, puis dans le pod:
curl -fsSL https://code-server.dev/install.sh | sh
nohup code-server --bind-addr 0.0.0.0:8080 --auth none /workspace > /workspace/code-server.log 2>&1 &
URL:
Preparation training¶
Sur un volume vide, le chemin recommande pour un agent est de pousser le bootstrap versionne depuis un checkout local:
scp -P <TCP_PORT> scripts\runpod_agent_bootstrap.sh root@<PUBLIC_IP>:/tmp/runpod_agent_bootstrap.sh
ssh -p <TCP_PORT> root@<PUBLIC_IP> "sed -i 's/\r$//' /tmp/runpod_agent_bootstrap.sh && bash /tmp/runpod_agent_bootstrap.sh prepare-bg"
ssh -p <TCP_PORT> root@<PUBLIC_IP> 'bash /workspace/moore-llm-sota/scripts/runpod_agent.sh status'
Sous Windows PowerShell, ne pas envoyer directement Get-Content -Raw vers
Bash: les fins de ligne CRLF peuvent interrompre le script avant le bootstrap.
Le bootstrap recupere les variables RunPod depuis /proc/1/environ, clone moore-llm-sota branche main, puis delegue a scripts/runpod_agent.sh.
Depuis le pod, quand le repo existe:
cd /workspace
git clone --branch main https://github.com/BurkimbIA/moore-llm-sota.git
cd moore-llm-sota
Si le repo est prive et que le clone interactif echoue, utiliser GITHUB_ACCESS_TOKEN ou envoyer une archive depuis la machine locale. Le script projet accepte GITHUB_ACCESS_TOKEN et GITHUB_TOKEN.
Preparation:
export GITHUB_TOKEN="${GITHUB_ACCESS_TOKEN:-$GITHUB_TOKEN}"
export HF_TOKEN="<hf_token>"
bash /workspace/moore-llm-sota/scripts/runpod_agent.sh prepare-bg
bash /workspace/moore-llm-sota/scripts/runpod_agent.sh status
Logs recommandés:
nohup bash /workspace/moore-llm-sota/scripts/runpod_prepare.sh > /workspace/runpod_prepare.log 2>&1 &
tail -f /workspace/runpod_prepare.log
Signaux attendus dans le log:
Git LFS initialized.
Cloning into '/workspace/bia-llms'...
bia-llms==0.23.0
torch==2.8.0+cu128
unsloth==...
HF login OK: <user>
RunPod setup complete
Smoke training¶
Ne pas lancer directement un full run. Commencer par:
bash /workspace/moore-llm-sota/scripts/runpod_agent.sh doctor
bash /workspace/moore-llm-sota/scripts/runpod_agent.sh smoke-1.7b
bash /workspace/moore-llm-sota/scripts/runpod_agent.sh follow
Le smoke doit prouver:
- chargement du dataset prive
burkimbia/moore-instruct-v1; - chargement du modele
Qwen/Qwen3-1.7B; - detection CUDA;
- demarrage SFT/QLoRA;
- cap exact a
max_steps=30; - W&B actif dans le projet
moore-llm-sota; - pas de repetition massive des tags XML.
Full training¶
Le chemin officiel utilise le launcher du repo, pas des overrides --cli_config.*.
bash /workspace/moore-llm-sota/scripts/runpod_agent.sh full-1.7b
bash /workspace/moore-llm-sota/scripts/runpod_agent.sh status
Puis, seulement si le 1.7B est bon qualitativement:
Politique actuelle:
| Run | Modele | Longueur | Checkpoints | W&B | S3 |
|---|---|---|---|---|---|
smoke-1.7b |
Qwen/Qwen3-1.7B |
max_steps=30 |
non | oui | sync finale si configure |
full-1.7b |
Qwen/Qwen3-1.7B |
2 epochs |
toutes les 1000 steps, garder 3 |
oui | sync periodique + finale |
full-4b |
Qwen/Qwen3-4B |
2 epochs |
toutes les 1000 steps, garder 3 |
oui | sync periodique + finale |
Le launcher imprime cette politique au debut du log. Pour un full run, on doit voir num_epochs=2, save_steps=1000, wandb_enabled=True, puis les URI S3 configurees.
Chaque run cree aussi un dossier d'audit autonome:
/workspace/audit/moore-llm-sota/<run_id>/
run.log
progress.log
manifest.txt
resolved_config.yaml
train_command.txt
python_packages.txt
status.txt
run.log capture les sorties meme si la commande externe n'a pas redirige stdout. manifest.txt contient le run kind, les commits Git, le GPU, l'environnement masque et le chemin de la config resolue. progress.log ajoute un snapshot GPU/disque/checkpoints/process toutes les 60 secondes.
Observation des logs¶
Commandes utiles:
nvidia-smi
tail -120 /workspace/runpod_prepare.log
bash /workspace/moore-llm-sota/scripts/runpod_agent.sh logs
bash /workspace/moore-llm-sota/scripts/runpod_agent.sh progress
ps -ef | grep -E 'train.py|uv|python' | grep -v grep
du -sh /workspace/*
ls -lah /workspace/audit/moore-llm-sota/latest
tail -120 /workspace/audit/moore-llm-sota/latest/run.log
tail -80 /workspace/audit/moore-llm-sota/latest/progress.log
cat /workspace/audit/moore-llm-sota/latest/manifest.txt
Pour verifier S3 sans afficher de secret:
grep -E 'S3 sync|resolved run_kind|wandb_enabled|save_steps|num_epochs' /workspace/train-full-1.7b.log
Si SSH tombe mais MCP voit encore le pod RUNNING, verifier la fiche machine. Une note comme celle-ci indique une machine instable:
Dans ce cas, stopper le pod puis recreer ailleurs. Ne pas continuer a debuguer longuement une machine marquee en outage.
Retour d'experience du 29 mai 2026¶
Essai effectue:
- Pod MCP cree:
moore-qwen3-1-7b-smoke - GPU:
NVIDIA L40, 48 GB VRAM - Cout:
$0.69/h - Pod id:
pdkrf6lwy1opc5 - SSH teste OK au debut:
NVIDIA L40, 46068 MiB code-serverinstalle et lance sur8080uv sync --extra cu128 --all-groupsa termine et installebia-llms==0.23.0,torch==2.8.0+cu128,unsloth- Blocage initial:
huggingface-cliabsent dans l'environnement recent. Correction: ecrire le token HF dansHF_HOME/tokenet verifier viahuggingface_hub.whoami(). - Blocage GitHub: utiliser
GITHUB_ACCESS_TOKENet pas seulementGITHUB_TOKEN. - Incident final: la machine L40 a ete marquee par RunPod comme ayant une panne reseau, puis SSH a expire. Le pod a ete stoppe pour arreter le cout GPU.
Conclusion: le flux MCP fonctionne, mais il faut automatiser les fallbacks GPU et traiter les machines avec note d'outage comme non fiables.
Regles de securite et couts¶
- Ne jamais commiter les tokens.
- Ne pas mettre de tokens bruts dans les templates; utiliser
{{ RUNPOD_SECRET_* }}. - Preferer
GITHUB_ACCESS_TOKEN,HF_TOKEN,WANDB_API_KEYcomme noms standards. - Pour les full runs, W&B doit rester actif.
- Pour les full runs, S3 doit etre configure avec
REQUIRE_S3_SYNC=true. - Toujours observer
runpod_prepare.logavant de lancer le training. - Stopper un pod instable immediatement.
- Terminer un pod inutile si on n'a plus besoin du volume.