@@ -76,8 +76,29 @@ def create_local_venv(
7676
7777 logger .info (f"Creating new venv at { venv_path } " )
7878
79+ # Resolve `uv` to an absolute path: some Ray actor processes don't see
80+ # the container's image PATH (so /root/.local/bin/uv isn't reachable).
81+ # Fall back to a static uv binary bind-mounted via the lustre RL dir.
82+ uv_bin = shutil .which ("uv" )
83+ if not uv_bin :
84+ for candidate in (
85+ "/root/.local/bin/uv" ,
86+ "/opt/nemo_rl_venv/bin/uv" ,
87+ "/usr/local/bin/uv" ,
88+ os .path .join (git_root , ".uv-static" ),
89+ ):
90+ if os .path .exists (candidate ):
91+ uv_bin = candidate
92+ break
93+ if not uv_bin :
94+ raise RuntimeError (
95+ f"Could not find 'uv' on PATH or common install locations "
96+ f"(/root/.local/bin, /opt/nemo_rl_venv/bin, /usr/local/bin, "
97+ f"{ git_root } /.uv-static)"
98+ )
99+
79100 # Create the virtual environment
80- uv_venv_cmd = ["uv" , "venv" , "--allow-existing" , venv_path ]
101+ uv_venv_cmd = [uv_bin , "venv" , "--allow-existing" , venv_path ]
81102 subprocess .run (uv_venv_cmd , check = True )
82103
83104 # Execute the command with the virtual environment
@@ -87,14 +108,18 @@ def create_local_venv(
87108 # context.
88109 # https://docs.astral.sh/uv/concepts/projects/config/#project-environment-path
89110 env ["UV_PROJECT_ENVIRONMENT" ] = venv_path
111+ env ["PATH" ] = os .path .dirname (uv_bin ) + os .pathsep + env .get ("PATH" , "" )
90112
91113 # Split the py_executable into command and arguments
92114 exec_cmd = shlex .split (py_executable )
115+ # If py_executable invokes bare `uv`, rewrite to the resolved uv_bin path.
116+ if exec_cmd and exec_cmd [0 ] == "uv" :
117+ exec_cmd [0 ] = uv_bin
93118 # Command doesn't matter, since `uv` syncs the environment no matter the command.
94119 exec_cmd .extend (["echo" , f"Finished creating venv { venv_path } " ])
95120
96121 # Always run uv sync first to ensure the build requirements are set (for --no-build-isolation packages)
97- subprocess .run (["uv" , "sync" , "--directory" , git_root ], env = env , check = True )
122+ subprocess .run ([uv_bin , "sync" , "--directory" , git_root ], env = env , check = True )
98123 subprocess .run (exec_cmd , env = env , check = True )
99124
100125 # Return the path to the python executable in the virtual environment
0 commit comments