Buscar/Modificar código distribuido de entrenamiento e inferencia de aprendizaje automático sin romperlo

Modificar código distribuido de entrenamiento e inferencia de aprendizaje automático sin romperlo

Para cambiar software que entrena o ejecuta modelos de aprendizaje automático en muchos procesos o aceleradores. Consulta antes de cambios riesgosos, alinea versiones de pesos y orden de operaciones colectivas en cada rango, mantiene compatible la configuración y reporta pruebas omitidas.

Para usar estas reglas de IA
## Leer el código primero y consultar antes de cambiar la configuración compartida o las API Antes de editar, lee la implementación pertinente, los patrones de los módulos cercanos, los contratos de configuración y las pruebas. Utiliza el gestor de entornos, el formateador, el analizador estático y la cadena de herramientas de pre-commit del proyecto; no eludas los hooks. Nunca codifiques de forma fija credenciales, rutas de máquinas, endpoints de servicios ni la topología del clúster. No deduzcas por conjetura la configuración del planificador ni reconstruyas los controladores y la pila de ejecución del acelerador como atajo para solucionar problemas. Obtén una decisión explícita antes de: - cambiar estructuras de configuración compartidas; - añadir dependencias; - modificar el comportamiento del lanzador o del planificador; - eliminar o cambiar de nombre API públicas, o modificarlas de forma incompatible. Si no se dispone del hardware necesario o de acceso al clúster, indica qué comprobaciones de integración se omitieron y por qué. No conviertas en código una suposición distribuida que no se haya verificado. Encamina el trabajo según el subsistema: motor de entrenamiento, motor de inferencia, algoritmo, lanzador, planificador, conjunto de datos, recompensa, flujo de trabajo o depuración distribuida. Cuando exista una guía de implementación especializada o una vía de revisión del dominio, utiliza la que ofrece el proyecto. ## Separar cada subsistema y marcar los datos con su versión de pesos Mantén como responsabilidades diferenciadas la orquestación, la generación de rollouts, el entrenamiento, la inferencia, la infraestructura, la adaptación de modelos, las recompensas, los conjuntos de datos y las utilidades transversales. El entrenador coordina el bucle, la carga de datos y los flujos de trabajo. Los flujos de trabajo de rollout definen la generación asíncrona de episodios. Los motores de inferencia generan salidas y reciben actualizaciones de pesos; los motores de entrenamiento consumen tensores de rollout, calculan actualizaciones y publican nuevas versiones de los pesos. En los sistemas asíncronos, adjunta metadatos explícitos de la versión de los pesos tanto a los datos generados como a las actualizaciones. Nunca entrenes ni evalúes con versiones del modelo que no coincidan sin que se advierta. Emite las métricas mediante el sistema de seguimiento estándar, conserva los artefactos bajo la raíz de salida configurada y utiliza la ruta canónica de guardado y recuperación de los checkpoints. La observabilidad y la recuperación forman parte del contrato de ejecución. Prefiere la composición y la delegación a una jerarquía de herencia profunda. Mantén los límites de extensión lo bastante reducidos como para poder probar por separado los motores, los flujos de trabajo y los adaptadores de modelos. ## Escribir código rápido para aceleradores sin sincronizar el dispositivo con el host Sigue las convenciones existentes de nomenclatura, tipado y registro del módulo responsable. Utiliza anotaciones de tipo e importaciones explícitas; nunca uses importaciones con comodines. Mantén las dependencias opcionales pesadas dentro de las funciones o rutas de código que las necesiten. Utiliza el registrador del proyecto en lugar de imprimir directamente. Incluye en los registros el contexto del componente y del rango distribuido para que sea posible atribuir el origen de las salidas concurrentes. En las rutas críticas del acelerador: - evita la sincronización del dispositivo con el host, como extraer valores escalares o listas para registrarlos; - agrupa las operaciones con tensores, en vez de recorrer elementos individuales en Python; - establece explícitamente el dispositivo y el tipo de datos; - comprueba mediante aserciones las formas esperadas de los tensores en los límites. Mantén los flujos de trabajo de rollout sin bloqueos. Espera las llamadas asíncronas a los motores y las operaciones con archivos; no introduzcas E/S síncrona en una ruta asíncrona de episodios. Para una función nueva, sigue el patrón del módulo funcional más cercano, añade pruebas específicas y evita las refactorizaciones ajenas al cambio. ## Cambiar campos de configuración y API públicas sin romper a quien los usa Ordena los campos de configuración empezando por los obligatorios, seguidos de los opcionales habituales, los opcionales poco frecuentes y, por último, los internos. Valídalos durante la inicialización mediante una excepción clara que identifique el valor o la restricción no válidos. Añade los campos públicos con valores predeterminados seguros. Márcalos como obsoletos antes de eliminarlos y evita cambiar los tipos establecidos de los campos. Las clases de configuración públicas deben documentar sus restricciones y valores aceptados. Representa las opciones finitas de la línea de comandos mediante tipos restringidos en vez de cadenas de formato libre. Reutiliza las clases de datos canónicas de configuración, en lugar de crear estructuras paralelas. Considera la configuración compartida, los lanzadores, los planificadores y los nombres de las API públicas como áreas de gran impacto. Explicita el efecto sobre la compatibilidad en la descripción del cambio y obtén aprobación antes de realizar modificaciones destructivas o incompatibles. Cuando no sea posible decidir el comportamiento correcto a partir de los contratos actuales, deja un marcador de seguimiento con un alcance claramente definido e informa de la restricción pendiente, en vez de inventar un valor predeterminado. ## Mantener coherentes los grupos de procesos y las operaciones colectivas en todos los rangos Nunca crees un grupo de procesos global en el momento de la importación. Pasa explícitamente el grupo de procesos previsto y, cuando importe la pertenencia al grupo, consulta el rango con respecto a ese grupo. Mantén las dimensiones de la malla de dispositivos alineadas con el modelo de paralelismo declarado, incluidos, cuando corresponda, los ejes de fragmentación de datos, tensores, contexto, expertos y tensores de expertos. Las operaciones colectivas son contratos globales: - todos los rangos participantes deben invocar la misma operación all-reduce y en el mismo orden; - selecciona deliberadamente la operación de reducción, como suma frente a promedio; - las operaciones de broadcast deben indicar un rango de origen explícito; - las barreras son herramientas de diagnóstico, no una estrategia habitual de sincronización. Diagnostica los bloqueos comprobando si las secuencias de operaciones colectivas no coinciden. Diagnostica los resultados incorrectos comprobando la semántica de reducción y las versiones de los pesos. Diagnostica los errores por falta de memoria comprobando la fragmentación, la ubicación de los tensores y la propiedad de los dispositivos antes de reducir la funcionalidad del modelo. Utiliza diagnósticos detallados de la ejecución distribuida, de la biblioteca de comunicaciones y del lanzamiento síncrono solo para una depuración específica, y elimínalos o desactívalos una vez comprendido el problema. ## Probar el código distribuido y anotar en la pull request las pruebas omitidas Nombra las pruebas de modo que expresen el comportamiento, la condición y el resultado esperado, y estructúralas en preparar, ejecutar y verificar. Marca las pruebas lentas, asíncronas, de aceleradores y distribuidas para que la CI predeterminada pueda seleccionar las suites correctas. Omite de forma controlada las pruebas de aceleradores o de varios nodos que no estén disponibles e indica explícitamente el motivo. Utiliza el grupo de procesos simulado del framework para probar el comportamiento distribuido a nivel de unidad; no simules los mecanismos internos de fragmentación profunda ni de tensores distribuidos cuya semántica deba verificar la prueba. Compara los tensores con tolerancias relativas y absolutas explícitas. Prefiere las rutas temporales administradas y la aplicación de monkeypatches con un alcance limitado. Ejecuta primero la suite unitaria de alcance reducido y, cuando el hardware lo permita, la suite distribuida o de aceleradores directamente afectada. Antes de enviar el cambio, ejecuta la cadena completa de formateo y pre-commit. Genera la documentación de referencia de la línea de comandos mediante el generador canónico. Genera la documentación de la versión mediante el wrapper del proyecto que realiza la configuración estática y el empaquetado necesarios, y no mediante un comando de documentación de nivel inferior que omita pasos del proyecto. En la solicitud de incorporación de cambios, identifica el problema, las áreas de riesgo, los comandos de prueba exactos, las suites omitidas con sus motivos y cualquier limitación de hardware. Utiliza asuntos de commit convencionales y en imperativo, y elimina los commits de trabajo en curso antes de la revisión.