GPU para seus projetos · pagamento em cripto sem KYC Como alugar
Português
Abrir o console
Guia prático / KERNODECK

Seu notebook funciona. Você consegue executá-lo novamente sem as células?

Para passar de um notebook a um script, recomece de um kernel vazio, identifique as entradas e extraia o cálculo para funções. Em seguida, dê ao programa argumentos explícitos e um destino de saída separado. O sucesso se verifica em um novo processo, com um resultado esperado; exportar as células para um arquivo Python não é suficiente para tornar a experiência reprodutível.

8 min de leitura · Guia para desenvolvedores

1. Descobrir o que o kernel ainda sabe

O arquivo do notebook e o estado do kernel nem sempre contam a mesma história. Uma variável pode vir de uma célula excluída, uma lista pode ter sido modificada várias vezes, e um objeto carregado antes da última mudança de código pode permanecer na memória. Os resultados exibidos, portanto, não demonstram que as células atuais ainda produzem esses resultados na ordem visível.

Mantenha uma cópia de trabalho, reinicie o kernel e execute as células do início ao fim. Anote a primeira célula que falha ou muda de resultado. Procure a dependência ausente em vez de reinjetar manualmente uma variável de uma sessão antiga. O kernel do Jupyter é um processo separado; fechar uma aba não equivale a reconstruir um ambiente limpo.

Faça também um inventário dos efeitos externos: download, instalação de pacote, mudança de diretório, leitura de um arquivo já produzido e uso de uma variável de ambiente. Uma célula cujo resultado parece imediato pode simplesmente estar reutilizando um arquivo antigo. Seu futuro script deve conseguir distinguir uma entrada intencional de um resquício de teste.

2. Escrever o contrato antes de mover o código

Escolha uma única tarefa para extrair. Por exemplo: ler um arquivo de scores, reter os identificadores cujo score atinge um limite e escrever o resultado. O exemplo deste guia é didático, não executado e sem GPU. Ele serve para mostrar as dependências de uma execução, não para anunciar uma medição ou uma ferramenta fornecida com o Kernodeck.

Defina a entrada, o parâmetro e a saída com precisão suficiente para verificar a transformação. Aqui, o limite é inclusivo: um score igual a 0,5 é retido. Os identificadores devem permanecer associados aos seus scores e a ordem de entrada é preservada. Uma saída existente não deve ser substituída involuntariamente por um novo teste.

Esta etapa evita uma migração ambígua: se o notebook eliminasse os scores iguais ao limite enquanto o script os conserva, você mudou o cálculo. Decida explicitamente se isso é uma correção ou uma regressão. Mantenha um caso situado exatamente na fronteira, não apenas dois valores distantes.

Role a tabela para ler todas as colunas.
Contrato didático de seleção, sem execução alegada.
ElementoValor do exemploCritério
Entradaa: 0,4; b: 0,8; c: 0,5Três identificadores distintos, scores já validados entre 0 e 1.
ParâmetroLimite 0,5Comparação maior ou igual.
Saída esperadab, depois cDois identificadores, sem duplicação nem reordenação.

3. Extrair uma função que não depende mais de uma célula

Separe a transformação das operações de leitura e escrita. Uma função de cálculo recebe seus dados e seu limite e então retorna os identificadores selecionados. Ela não consulta uma variável global chamada limite, não abre implicitamente um arquivo e não modifica a lista de entrada. Isso permite que o notebook e o script chamem exatamente o mesmo cálculo.

No trecho, os dados são supostos já validados conforme o contrato anterior. Portanto, a função não constitui um validador completo de arquivo. Essa limitação é intencional: verifique os formatos na entrada do programa e depois mantenha a transformação fácil de entender. Adicionar um parâmetro não deve exigir encontrar a célula que havia alterado um valor.

O notebook pode continuar sendo sua ferramenta de exploração. Faça com que ele importe essa função em vez de manter uma segunda cópia. Após modificar o módulo, parta de um kernel novo para comparar os dois caminhos; uma função antiga já importada não deve distorcer a verificação.

Função didática — a ser colocada no seu próprio módulo, não executada aqui
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. Tornar os parâmetros uma entrada visível

O ponto de entrada do script processa os argumentos, valida as escolhas e chama as funções. O módulo padrão argparse descreve as opções e gera uma ajuda; ele não conhece suas regras de negócio. Um float aceito sintaticamente ainda pode estar fora do intervalo permitido. O limite deste exemplo exige, portanto, uma verificação adicional.

Especifique a resolução de caminhos: relativos ao diretório a partir do qual o comando é iniciado, ou a uma pasta de projeto explicitamente escolhida. Não use uma mudança de diretório oculta no meio do cálculo. O bloco abaixo mostra apenas a análise dos argumentos; a leitura dos dados e a escrita ainda precisam ser conectadas no programa do leitor.

Mantenha os segredos fora desses argumentos. Os parâmetros compartilháveis descrevem a experiência; os acessos a um repositório ou armazenamento seguem outro canal. Um comando útil para um colega deve poder ser copiado sem copiar também um token.

Análise pedagógica de argumentos — trecho não executado
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("Le seuil doit être compris entre 0 et 1.")
    return args

5. Dê ao script um fim e saídas verificáveis

Coloque a orquestração em uma função main e acione-a sob a condição if __name__ == "__main__". O módulo pode assim ser importado pelo notebook sem iniciar imediatamente o processamento. Os imports definem as ferramentas; a entrada principal decide quando ler, calcular e escrever.

Atribua uma pasta distinta a cada execução. Registre os parâmetros não sensíveis realmente usados e a identidade da entrada, depois escreva os resultados. Para a nossa seleção, verifique o número de identificadores, sua pertinência à entrada e a regra do limite. Um arquivo JSON bem formado pode conter os identificadores errados; sua presença sozinha não basta.

Preveja uma falha explícita se o arquivo de entrada estiver faltando ou se o destino não for utilizável. Evite substituir esses problemas por uma lista vazia: ela poderia ser interpretada como uma seleção válida. O programa deve distinguir nenhum resultado que atenda ao limite e nenhum resultado porque a leitura falhou.

6. Comparar em duas execuções novas

Use primeiro as três linhas pedagógicas. Com o limite 0,5, espere b e c; com 0,9, espere uma lista vazia; com 0,4, espere os três identificadores. Essas respostas deduzem-se do contrato e não são apresentadas como resultados executados aqui. Elas permitem identificar um operador de comparação invertido ou uma ordem errada.

Execute em seguida seu notebook reiniciado e seu script em um processo novo, sobre a mesma entrada. Compare os valores úteis, não as capturas de tela nem os horários inscritos nos arquivos. Adicione um segundo conjunto representativo e uma entrada inválida. Documente as diferenças esperadas, como uma apresentação mais sóbria das saídas.

Uma conversão nbconvert pode acelerar a movimentação inicial das células, mas seus comandos mágicos ainda podem depender do Jupyter. Remova ou substitua as instruções próprias do notebook, as exibições inúteis e as instalações improvisadas. A exportação é um ponto de partida; a comparação a partir de um estado novo decide se a migração está concluída.

7. Passar para a GPU sem reintroduzir o estado oculto

Uma vez compreendido o percurso na CPU, conecte o carregamento do modelo e o backend à mesma estrutura explícita. Mantenha versões, precisão, entrada e destino. A passagem para a GPU não corrige nem uma ordem de células incoerente nem um arquivo produzido por um teste antigo. Verifique separadamente que o PyTorch pode realmente calcular no dispositivo escolhido.

Se dois lançamentos produzirem valores diferentes, distinga um estado esquecido, uma fonte aleatória e os limites numéricos do cálculo. Uma semente não é uma promessa universal de identidade entre versões e hardwares. Para o treinamento interrompido, use o procedimento dedicado aos checkpoints: este guia transforma o ponto de entrada, sem reconstituir os estados de otimizador ou de geradores.

A saída útil é um programa que você pode descrever em um comando, com seus pré-requisitos e uma verificação de resultado. O notebook continua livre para explorar e traçar; ele não carrega mais sozinho a memória de como o cálculo deve ser iniciado.

Suas perguntas

Devo abandonar os notebooks para tornar um projeto reproduzível?

Não. Mantenha o notebook para explorar e apresentar, mas coloque o cálculo reutilizado em funções ou módulos chamados também pelo script. A verificação deve partir de um kernel novo e de entradas explícitas.

Exportar um notebook para .py é suficiente?

Não. A exportação desloca o código visível; ela não corrige a ordem das dependências nem os efeitos de células já executadas. Comandos mágicos ainda podem exigir o Jupyter. Verifique o script em um novo processo.

Devo obter arquivos idênticos byte a byte?

Somente se esse critério for pertinente para o seu formato. Compare primeiro os identificadores, valores e regras de negócio esperados. Datas ou metadados podem diferir sem alterar o cálculo; as tolerâncias numéricas devem ser explícitas.