Script para macOS Apple Silicon (M1 / M2 / M3) + Jupyter
import os import sys import shutil import subprocess from textwrap import dedent
respuesta = input(
"
if respuesta.strip() != "SI": print("❌ Ejecución cancelada por el usuario.") sys.exit(0)
ENV_NAME = "tf-metal311"
KERNEL_DISPLAY_NAME = "Python (tf-metal311)"
INSTALL_YOLO = True
INSTALL_TF_METAL = True
TF_VERSION = "2.18.0" TF_METAL_VERSION = "1.2.0"
============================================================
============================================================
YOLO_PKGS = [ "ultralytics", "opencv-python", "matplotlib", "pyyaml", "ipykernel", # Necesario para registrar el kernel en Jupyter ]
TF_METAL_PKGS = [ f"tensorflow=={TF_VERSION}", f"tensorflow-metal=={TF_METAL_VERSION}", ]
============================================================
============================================================
def detect_conda(): """ Intenta localizar el ejecutable 'conda' incluso cuando Jupyter no hereda correctamente el PATH del sistema.
Estrategia:
- Probar si 'conda' está disponible en PATH
- Probar rutas típicas de Anaconda / Miniconda / Miniforge en macOS
Devuelve:
- ruta a 'conda' si se encuentra
- lista de rutas probadas (útil para mensajes de error) """ tried = []
p = shutil.which("conda") if p: return p, tried
home = os.path.expanduser("~") candidates = [ os.path.join(home, "anaconda3", "bin", "conda"), os.path.join(home, "miniconda3", "bin", "conda"), os.path.join(home, "miniforge3", "bin", "conda"), os.path.join(home, "mambaforge", "bin", "conda"), "/opt/anaconda3/bin/conda", "/opt/miniconda3/bin/conda", "/opt/miniforge3/bin/conda", "/opt/mambaforge/bin/conda", ]
for c in candidates: tried.append(c) if os.path.exists(c) and os.access(c, os.X_OK): return c, tried
return None, tried
============================================================
============================================================
def run(cmd): """ Ejecuta un comando externo mostrando exactamente qué se ejecuta. Si el comando falla, se lanza una excepción (fail fast). """ print("\n>>", " ".join(cmd)) subprocess.run(cmd, check=True)
def ensure_mac(): """ Verifica que el sistema operativo es macOS. TensorFlow + Metal solo tiene sentido en este entorno. """ if sys.platform != "darwin": raise RuntimeError( "Este script está diseñado exclusivamente para macOS (Apple Silicon)." )
============================================================
============================================================
def main():
ensure_mac()
conda_path, tried = detect_conda() if not conda_path: raise RuntimeError(dedent(f""" No se ha podido localizar 'conda'.
Rutas probadas:
- """ + "\n - ".join(tried) + """
Posible solución:
- Abre Terminal y ejecuta: which conda
- Añade esa ruta a la lista de 'candidates' """).strip())
print("✅ Usando conda en:", conda_path)
print(f"\nCreando entorno '{ENV_NAME}' con Python 3.11...") try: run([conda_path, "create", "-n", ENV_NAME, "python=3.11", "-y"]) except subprocess.CalledProcessError: print(f"(Info) El entorno '{ENV_NAME}' ya existe. Continúo.")
run([ conda_path, "run", "-n", ENV_NAME, "python", "-m", "pip", "install", "--upgrade", "pip" ])
if INSTALL_YOLO: print("\nInstalando paquetes de visión / YOLO...") run([ conda_path, "run", "-n", ENV_NAME, "python", "-m", "pip", "install", *YOLO_PKGS ])
if INSTALL_TF_METAL: print("\nInstalando TensorFlow + Metal (versiones fijadas)...") for pkg in TF_METAL_PKGS: print(" -", pkg)
run([ conda_path, "run", "-n", ENV_NAME, "python", "-m", "pip", "install", "--no-cache-dir", "--force-reinstall", *TF_METAL_PKGS ])
print("\nRegistrando kernel de Jupyter...") run([ conda_path, "run", "-n", ENV_NAME, "python", "-m", "ipykernel", "install", "--user", "--name", ENV_NAME, "--display-name", KERNEL_DISPLAY_NAME ])
if INSTALL_TF_METAL: print("\nValidación de TensorFlow y GPU Metal...") run([ conda_path, "run", "-n", ENV_NAME, "python", "-c", ( "import tensorflow as tf; " "print('TensorFlow:', tf.version); " "print('GPUs:', tf.config.list_physical_devices('GPU'))" ) ])
print(dedent(f""" ✅ Entorno configurado correctamente.
En Jupyter: Kernel → Change Kernel → {KERNEL_DISPLAY_NAME}
Para desinstalar:
- Quitar kernel: jupyter kernelspec uninstall {ENV_NAME}
- Borrar entorno: {conda_path} remove -n {ENV_NAME} --all -y """).strip())
============================================================
============================================================
main()