1. Recuperar lo que el kernel aún sabe
El archivo del notebook y el estado del kernel no siempre cuentan la misma historia. Una variable puede venir de una celda eliminada, una lista haber sido modificada varias veces, y un objeto cargado antes del último cambio de código seguir en memoria. Los resultados mostrados no demuestran, por tanto, que las celdas actuales sigan produciendo esos resultados en su orden visible.
Conserva una copia de trabajo, reinicia el kernel y luego ejecuta las celdas de principio a fin. Anota la primera celda que falla o cambia de resultado. Busca la dependencia que falta en lugar de reinyectar manualmente una variable desde una sesión anterior. El kernel de Jupyter es un proceso independiente; cerrar una pestaña no equivale a reconstruir un entorno limpio.
Inventaría también los efectos externos: descarga, instalación de paquetes, cambio de directorio, lectura de un archivo ya generado y uso de una variable de entorno. Una celda cuyo resultado parece inmediato puede simplemente estar reutilizando un archivo antiguo. Tu futuro script debe poder distinguir una entrada intencional de un resto de prueba.
2. Escribir el contrato antes de mover el código
Elige una sola tarea para extraer. Por ejemplo: leer un archivo de puntuaciones, quedarte con los identificadores cuya puntuación alcanza un umbral y escribir el resultado. El ejemplo de esta guía es pedagógico, no se ejecuta y no usa GPU. Sirve para mostrar las dependencias de una ejecución, no para anunciar una medición ni una herramienta incluida con Kernodeck.
Define la entrada, el parámetro y la salida con la precisión suficiente para verificar la transformación. Aquí, el umbral es inclusivo: una puntuación igual a 0,5 se conserva. Los identificadores deben permanecer asociados a sus puntuaciones y se conserva el orden de entrada. Una salida existente no debe reemplazarse involuntariamente por una nueva prueba.
Este paso evita una migración ambigua: si el notebook eliminaba las puntuaciones iguales al umbral mientras que el script las conserva, has cambiado el cálculo. Decide explícitamente si es una corrección o una regresión. Conserva un caso situado exactamente en la frontera, no solo dos valores alejados.
Desplaza la tabla para leer todas las columnas.| Elemento | Valor del ejemplo | Criterio |
|---|---|---|
| Entrada | a: 0,4; b: 0,8; c: 0,5 | Tres identificadores distintos, puntuaciones ya validadas entre 0 y 1. |
| Parámetro | Umbral 0,5 | Comparación mayor o igual. |
| Salida esperada | b, luego c | Dos identificadores, sin duplicación ni reordenación. |
3. Extraer una función que ya no dependa de una celda
Separa la transformación de las operaciones de lectura y escritura. Una función de cálculo recibe sus datos y su umbral, y luego devuelve los identificadores seleccionados. No consulta una variable global llamada umbral, no abre un archivo implícitamente y no modifica la lista de entrada. Esto permite que el notebook y el script llamen exactamente al mismo cálculo.
En el fragmento, se supone que los datos ya están validados según el contrato anterior. Por lo tanto, la función no constituye un validador completo de archivo. Esta limitación es intencional: verifica los formatos en la entrada del programa y luego mantén la transformación fácil de entender. Añadir un parámetro no debe obligarte a buscar la celda que había cambiado un valor.
El notebook puede seguir siendo tu herramienta de exploración. Haz que importe esta función en lugar de mantener una segunda copia. Tras modificar el módulo, parte de un kernel nuevo para comparar ambos recorridos; una función antigua ya importada no debe falsear la verificación.
def retenir_identifiants(records, seuil):
return [
record["id"]
for record in records
if record["score"] >= seuil
]
if __name__ == "__main__":
records = [
{"id": "a", "score": 0.4},
{"id": "b", "score": 0.8},
{"id": "c", "score": 0.5},
]
attendu = ["b", "c"]
obtenu = retenir_identifiants(records, 0.5)
if obtenu != attendu:
raise SystemExit("Sélection inattendue")4. Convertir los parámetros en una entrada visible
El punto de entrada del script procesa los argumentos, valida las opciones y llama a las funciones. El módulo estándar argparse describe las opciones y genera una ayuda; no conoce tus reglas de negocio. Un flotante aceptado sintácticamente aún puede estar fuera del intervalo permitido. Por lo tanto, el umbral de este ejemplo requiere una comprobación adicional.
Especifica la resolución de las rutas: relativas al directorio desde el que se lanza el comando, o a una carpeta de proyecto elegida explícitamente. No uses un cambio de directorio oculto en medio del cálculo. El bloque de abajo muestra únicamente el análisis de los argumentos; la lectura de los datos y la escritura quedan pendientes de conectar en el programa del lector.
Mantén los secretos fuera de estos argumentos. Los parámetros compartibles describen la experiencia; los accesos a un repositorio o a un almacenamiento siguen otro canal. Un comando útil para un colega debe poder copiarse sin copiar también un token.
import argparse
from pathlib import Path
def lire_arguments():
parser = argparse.ArgumentParser()
parser.add_argument("--input", required=True, type=Path)
parser.add_argument("--output", required=True, type=Path)
parser.add_argument("--seuil", required=True, type=float)
args = parser.parse_args()
if not 0 <= args.seuil <= 1:
parser.error("El umbral debe estar entre 0 y 1.")
return args5. Dar al script un final y salidas verificables
Coloca la orquestación en una función main y actívala bajo la condición if __name__ == "__main__". Así el módulo puede importarse desde el notebook sin lanzar el procesamiento de inmediato. Los imports definen las herramientas; la entrada principal decide cuándo leer, calcular y escribir.
Asigna una carpeta distinta a cada ejecución. Guarda los parámetros no sensibles realmente usados y la identidad de la entrada, y luego escribe los resultados. Para nuestra selección, verifica el número de identificadores, su pertenencia a la entrada y la regla del umbral. Un archivo JSON bien formado puede contener los identificadores equivocados; su sola presencia no basta.
Prevé un fallo explícito si falta el archivo de entrada o si el destino no es utilizable. Evita sustituir estos problemas por una lista vacía: esta podría interpretarse como una selección válida. El programa debe distinguir ningún resultado que cumpla el umbral de ningún resultado porque la lectura ha fallado.
6. Comparar en dos ejecuciones nuevas
Usa primero las tres líneas didácticas. Con el umbral 0,5, espera b y c; con 0,9, espera una lista vacía; con 0,4, espera los tres identificadores. Estas respuestas se deducen del contrato y no se presentan como resultados ejecutados aquí. Permiten detectar un operador de comparación invertido o un orden incorrecto.
Ejecuta después tu notebook reiniciado y tu script en un proceso nuevo, sobre la misma entrada. Compara los valores útiles, no las capturas de pantalla ni las horas registradas en los archivos. Añade un segundo conjunto representativo y una entrada inválida. Documenta las diferencias esperadas, como una presentación más sobria de las salidas.
Una conversión nbconvert puede acelerar el traslado inicial de las celdas, pero sus comandos mágicos pueden seguir dependiendo de Jupyter. Elimina o sustituye las instrucciones propias del notebook, las visualizaciones innecesarias y las instalaciones improvisadas. La exportación es un punto de partida; la comparación desde un estado nuevo decide si la migración ha terminado.
7. Pasar a la GPU sin reintroducir el estado oculto
Una vez comprendido el recorrido en CPU, conecta la carga del modelo y el backend a la misma estructura explícita. Conserva versiones, precisión, entrada y destino. El paso a la GPU no corrige ni un orden de celdas incoherente ni un archivo producido por un ensayo anterior. Verifica por separado que PyTorch puede realmente calcular en el dispositivo elegido.
Si dos lanzamientos producen valores diferentes, distingue un estado olvidado, una fuente aleatoria y los límites numéricos del cálculo. Una semilla no es una promesa universal de identidad entre versiones y hardware. Para el entrenamiento interrumpido, usa el procedimiento dedicado a los checkpoints: esta guía transforma el punto de entrada, sin reconstituir los estados del optimizador o de los generadores.
El resultado útil es un programa que puedes describir en un solo comando, con sus requisitos previos y una comprobación de resultado. El notebook queda libre para explorar y trazar; ya no es el único que guarda la memoria de cómo debe lanzarse el cálculo.