> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://fr.nvidia-localization.ferndocs.com/fr/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://fr.nvidia-localization.ferndocs.com/fr/_mcp/server.

# uv dans NeMo RL

Nous utilisons le gestionnaire de packages Python `uv` pour gérer les dépendances dans NeMo RL.

## Vue d'ensemble

`uv` est un outil incroyable qui simplifie notre flux de travail et est extrêmement rapide car il est écrit en Rust. Ce document explique pourquoi nous avons adopté `uv` pour la gestion de packages dans notre dépôt, en particulier pour NeMo RL, et comment il nous aide à gérer les dépendances dans les clusters Ray.

## Pourquoi `uv` ?

`uv` apporte les avantages clés suivants à notre workflow de développement Python :

### Vitesse et Efficacité

* Écrit en Rust, le rendant significativement plus rapide que les gestionnaires de packages Python traditionnels.
* Mécanismes de mise en cache optimisés qui réduisent les téléchargements et installations redondants.
* Création et commutation d'environnements rapides, permettant des cycles de développement rapides.

### Environnements Isolés

* Crée des environnements Python complètement isolés, empêchant les conflits de dépendances entre les packages système et les packages spécifiques au projet.
* Évite les situations de dépendances nuancées où un script Python pourrait accidentellement utiliser à la fois les dépendances virtualenv et les dépendances système.
* Assure un comportement cohérent sur différentes machines et environnements de déploiement.

### Gestion des Dépendances dans les Clusters Ray

* Permet la gestion d'environnements Python hétérogènes dans un cluster Ray.
* Fournit de la flexibilité pour que chaque acteur (worker) utilise les dépendances Python spécifiques dont il a besoin.
* Simplifie la propagation des environnements aux nœuds workers sans configuration manuelle sur chaque nœud.

### Flexibilité sans Conteneur

* Nous libère de la nécessité de publier de nombreux conteneurs pour différentes combinaisons de dépendances.
* Nous permet de définir différents [groupes de dépendances](https://docs.astral.sh/uv/concepts/projects/dependencies/#dependency-groups) et [extras](https://docs.astral.sh/uv/concepts/projects/dependencies/#optional-dependencies) et de sélectionner dynamiquement ceux dont nous avons besoin.
* Réduit la complexité de l'infrastructure et la surcharge de maintenance.

## Mise en Œuvre dans NeMo RL

Cette section décrit comment les workers définissent leurs exécutables requis, détaille les configurations prédéfinies disponibles (comme BASE ou VLLM), et explique comment personnaliser ces configurations pour des besoins spécifiques, en assurant la cohérence entre les acteurs.

### Configuration du Worker

Dans notre base de code, les workers (classes décorées avec `@ray.remote`, par exemple `PolicyWorker`) sont associés à un `PY_EXECUTABLE` qui spécifie les dépendances dont le worker a besoin. Ceux-ci sont définis dans un registre global dans [`ACTOR_ENVIRONMENT_REGISTRY`](../../nemo_rl/distributed/ray_actor_environment_registry.py). Cela permet à différentes parties de notre application d'avoir leurs propres environnements personnalisés.

### Exécutables Python Pris en Charge

Nous fournissons plusieurs configurations d'exécutables Python prédéfinies dans `PY_EXECUTABLES` :

```python
class PY_EXECUTABLES:
    SYSTEM = sys.executable

    # Use NeMo RL direct dependencies.
    BASE = "uv run --locked"

    # Use NeMo RL direct dependencies and vllm.
    VLLM = "uv run --locked --extra vllm"
```

Pour assurer des dépendances cohérentes entre les acteurs, nous exécutons avec `--locked` pour garantir que les dépendances sont cohérentes avec le contenu de `uv.lock`.

### Personnalisation

Si vous avez besoin d'une configuration d'exécutable Python différente, vous pouvez remplacer celle par défaut en passant la vôtre dans `RayWorkerBuilder.__call__`. Cela offre de la flexibilité pour des cas d'utilisation spéciaux sans modifier les configurations de base.

## Comment Cela Fonctionne

Lorsqu'un job NeMo RL est démarré :

1. Le script pilote crée plusieurs `RayWorkerGroup`.
2. Chaque groupe de workers créera leurs workers qui sont encapsulés dans un `RayWorkerBuilder` où le nom complètement qualifié (FQN) de la classe worker est passé en tant que chaîne.
3. `RayWorkerBuilder` lance le worker sous `RayWorkerBuilder` qui nous permet d'initialiser la classe sans importer des packages non disponibles dans l'environnement de base.
4. Avant que la classe worker ne soit instanciée par le `RayWorkerBuilder`, le FQN est utilisé pour rechercher -- dans un [registre global](../../nemo_rl/distributed/ray_actor_environment_registry.py)) -- pour déterminer quel membre de `PY_EXECUTABLES` doit être utilisé pour lancer ce jeu de workers. Si le `PY_EXECUTABLES.*` choisi commence par `uv` ; un `venv` est créé avec toutes les dépendances dont il a besoin et le `runtime_env["py_executable"]` est remplacé par l'interpréteur python du `venv`.

Cette approche permet un démarrage rapide et maintient l'isolation des dépendances. Elle a également l'avantage supplémentaire d'avoir tous les environnements virtuels localement sous `./venvs`.

## Conclusion

Utiliser `uv` pour la gestion des dépendances dans NeMo RL nous offre un moyen rapide, flexible et fiable de gérer les dépendances Python dans les clusters Ray distribués. Il élimine de nombreux points douloureux traditionnels de la gestion des dépendances dans les systèmes distribués, tout en permettant des environnements hétérogènes qui peuvent être adaptés à des charges de travail spécifiques.