GPU para tus proyectos · pago en cripto sin KYC Cómo alquilar
Español
Abrir la consola
Guía práctica / KERNODECK

Tu notebook funciona. ¿Puedes reejecutarlo sin sus celdas?

Para pasar de un notebook a un script, parte de un kernel vacío, identifica las entradas y extrae el cálculo en funciones. Da después al programa argumentos explícitos y un destino de salida distinto. El éxito se verifica en un nuevo proceso, con un resultado esperado; exportar las celdas a un archivo Python no basta para hacer la experiencia reproducible.

8 min de lectura · Guía para desarrolladores

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.
Contrato pedagógico de selección, sin ejecución declarada.
ElementoValor del ejemploCriterio
Entradaa: 0,4; b: 0,8; c: 0,5Tres identificadores distintos, puntuaciones ya validadas entre 0 y 1.
ParámetroUmbral 0,5Comparación mayor o igual.
Salida esperadab, luego cDos 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.

Función pedagógica — para colocar en tu propio módulo, no se ejecuta aquí
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.

Análisis de argumentos didáctico — extracto no ejecutado
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 args

5. 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.

Tus preguntas

¿Hay que abandonar los notebooks para hacer reproducible un proyecto?

No. Conserva el notebook para explorar y presentar, pero coloca el cálculo reutilizado en funciones o módulos que también llame el script. La verificación debe partir de un kernel nuevo y de entradas explícitas.

¿Basta con exportar un notebook a .py?

No. La exportación traslada el código visible; no arregla el orden de las dependencias ni los efectos de celdas ya ejecutadas. Los comandos mágicos pueden seguir necesitando Jupyter. Verifica el script en un proceso nuevo.

¿Debo obtener archivos idénticos byte a byte?

Solo si ese criterio es relevante para tu formato. Compara primero los identificadores, valores y reglas de negocio esperados. Las fechas o los metadatos pueden diferir sin cambiar el cálculo; las tolerancias numéricas deben ser explícitas.