Salvamento e carregamento de um Pipeline com joblib
Os alunos serializarão um Pipeline ajustado em disco com joblib.dump e o recarregarão em uma nova sessão do Python para fazer previsões sem treinar novamente.
Salvamento e carregamento de um Pipeline com joblib é uma aula grátis de Machine Learning Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Machine Learning Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Machine Learning Academy inclui 4 aulas no total.
Por que persistir um fluxo treinado?
Treinar um fluxo de aprendizado de máquina pode levar minutos ou horas. Depois de ajustá-lo, você deve salvá-lo em disco para poder carregá-lo posteriormente e fazer previsões sem treiná-lo novamente. A persistência também é essencial para a implantação: você treina em uma máquina de desenvolvimento e fornece previsões em um servidor de produção. O arquivo salvo deve incluir tanto as etapas de pré-processamento quanto os pesos do modelo.
Duas opções de serialização: pickle e joblib
O módulo pickle integrado ao Python pode serializar qualquer objeto Python, incluindo fluxos do sklearn. joblib é uma biblioteca de terceiros (incluída no scikit-learn) geralmente preferida para objetos de aprendizado de máquina, pois é mais eficiente com arrays NumPy grandes — usando mapeamento de memória em vez de cópia — e pode compactar automaticamente o arquivo de saída.
import pickle
import joblib
# Both approaches work; joblib is recommended for sklearn objects
print('pickle version:', pickle.HIGHEST_PROTOCOL)
import sklearn
print('sklearn version:', sklearn.__version__)Salvando com joblib.dump
joblib.dump(obj, filename) serializa o fluxo em um arquivo. Opcionalmente, você pode definir compress=3 para usar compactação zlib (níveis de 1 a 9; 3 equilibra velocidade e tamanho). A função retorna uma lista dos arquivos criados. Para a maioria dos fluxos, é criado um único arquivo .pkl ou .joblib.
import joblib
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
pipe = Pipeline([
('scaler', StandardScaler()),
('clf', LogisticRegression(C=1.0, max_iter=200))
])
pipe.fit(X, y)
# Save
joblib.dump(pipe, '/tmp/iris_pipeline.joblib')
print('Pipeline saved!')Carregando com joblib.load
joblib.load(filename) desserializa o fluxo de volta para um objeto Python. O fluxo carregado é idêntico ao original: tem os mesmos parâmetros ajustados do padronizador (média e variância) e os mesmos pesos do modelo. Você pode chamar predict, predict_proba ou score imediatamente, sem reajustá-lo.
import joblib
from sklearn.datasets import load_iris
import numpy as np
X, y = load_iris(return_X_y=True)
# Load the saved pipeline
loaded_pipe = joblib.load('/tmp/iris_pipeline.joblib')
# Predict and verify
predictions = loaded_pipe.predict(X[:5])
print('Predictions:', predictions)
print('Test accuracy:', loaded_pipe.score(X, y).round(4))Verificando a fidelidade de ida e volta
Depois de carregar o fluxo, confirme se ele produz previsões idênticas às do original. Qualquer divergência indica um erro de serialização ou uma incompatibilidade de versões. Uma verificação simples consiste em comparar as previsões elemento a elemento usando np.array_equal.
import joblib
import numpy as np
from sklearn.datasets import load_iris
X, _ = load_iris(return_X_y=True)
# Reload and compare
loaded = joblib.load('/tmp/iris_pipeline.joblib')
# Reload the original reference predictions
# (in practice, save original predictions before reload)
original_preds = loaded.predict(X) # use loaded as reference
loaded2 = joblib.load('/tmp/iris_pipeline.joblib')
reloaded_preds = loaded2.predict(X)
print('Predictions match:', np.array_equal(original_preds, reloaded_preds))Opções de compactação no joblib
Fluxos grandes (por exemplo, com RandomForest de 1000 árvores) podem ocupar centenas de MB. Use joblib.dump(pipe, path, compress=3) para compactar durante a gravação. Como alternativa, especifique explicitamente o compactador: compress=('zlib', 3) ou compress=('lz4', 1) para obter a máxima velocidade. LZ4 é o mais rápido; zlib produz arquivos menores, mas é mais lento.
import joblib
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
import os
X, y = load_iris(return_X_y=True)
pipe = Pipeline([('sc', StandardScaler()), ('lr', LogisticRegression())]).fit(X, y)
# Uncompressed
joblib.dump(pipe, '/tmp/pipe_raw.joblib')
# Compressed
joblib.dump(pipe, '/tmp/pipe_compressed.joblib', compress=3)
print('Raw size:', os.path.getsize('/tmp/pipe_raw.joblib'), 'bytes')
print('Compressed size:', os.path.getsize('/tmp/pipe_compressed.joblib'), 'bytes')Usando pickle como alternativa
Se joblib não estiver disponível, pickle funciona com fluxos do sklearn. Use o modo binário ('rb'/'wb') ao abrir o arquivo. Para modelos pequenos ou ferramentas pontuais executadas por script, pickle é perfeitamente adequado; para sistemas de produção que lidam com arrays NumPy grandes, joblib é fortemente recomendado.
import pickle
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
pipe = Pipeline([('sc', StandardScaler()), ('lr', LogisticRegression())]).fit(X, y)
# Save with pickle
with open('/tmp/model.pkl', 'wb') as f:
pickle.dump(pipe, f)
# Load with pickle
with open('/tmp/model.pkl', 'rb') as f:
loaded = pickle.load(f)
print('Loaded score:', loaded.score(X, y).round(4))Avisos sobre compatibilidade de versões
Uma preocupação crítica em produção: um fluxo serializado com pickle no scikit-learn 1.2 pode não ser carregado corretamente no scikit-learn 1.5. Sempre registre as versões das bibliotecas usadas no treinamento em um arquivo de metadados junto ao modelo salvo. Use pip freeze > requirements.txt ou registre as versões programaticamente e armazene-as ao lado do arquivo do modelo.
import sklearn
import numpy as np
import json
import os
metadata = {
'sklearn_version': sklearn.__version__,
'numpy_version': np.__version__,
'model_file': 'iris_pipeline.joblib'
}
with open('/tmp/model_metadata.json', 'w') as f:
json.dump(metadata, f, indent=2)
print(json.dumps(metadata, indent=2))Carregando um fluxo em um script de produção
Em um serviço de produção, o fluxo de trabalho é: carregue o fluxo uma vez na inicialização (não a cada solicitação), receba os atributos de entrada, faça o pré-processamento com as transformações integradas ao fluxo e retorne as previsões. Como o fluxo inclui todo o pré-processamento, o código do serviço não precisa conhecer a padronização, a codificação ou o PCA — tudo isso está encapsulado no objeto salvo.
import joblib
import numpy as np
# At startup (once)
model = joblib.load('/tmp/iris_pipeline.joblib')
def predict(sepal_length, sepal_width, petal_length, petal_width):
features = np.array([[sepal_length, sepal_width, petal_length, petal_width]])
label = model.predict(features)[0]
proba = model.predict_proba(features)[0]
return {'label': int(label), 'confidence': round(float(proba.max()), 4)}
result = predict(5.1, 3.5, 1.4, 0.2)
print('Prediction result:', result)Considerações de segurança sobre modelos serializados com pickle
Nunca carregue um arquivo pickle de uma fonte não confiável. Arquivos pickle podem executar código arbitrário durante o carregamento — essa é uma limitação fundamental de segurança do Python. Para compartilhar modelos externamente, considere alternativas mais seguras e específicas para cada formato: ONNX para serialização entre estruturas, ou arquivos joblib compartilhados somente em uma infraestrutura confiável. Sempre verifique a soma de verificação do arquivo antes de carregá-lo.
import hashlib
def file_sha256(path):
h = hashlib.sha256()
with open(path, 'rb') as f:
for chunk in iter(lambda: f.read(65536), b''):
h.update(chunk)
return h.hexdigest()
checksum = file_sha256('/tmp/iris_pipeline.joblib')
print('Model SHA-256:', checksum)
# In production: compare this checksum with the one stored in your model registryTeste rápido de sanidade: carregar e prever
Uma prática recomendada final é incluir um pequeno script de teste de sanidade no pacote do modelo. Ele deve carregar o fluxo, executar uma entrada conhecida e verificar se a saída esperada é produzida. Execute esse teste no fluxo de integração e entrega contínuas sempre que o modelo for promovido para produção, confirmando que o arquivo não foi corrompido e que o ambiente é compatível.
import joblib
import numpy as np
# Sanity test
model = joblib.load('/tmp/iris_pipeline.joblib')
# Known input (setosa): sepal_length=5.1, sepal_width=3.5, petal_length=1.4, petal_width=0.2
X_test = np.array([[5.1, 3.5, 1.4, 0.2]])
pred = model.predict(X_test)[0]
# Iris class 0 = setosa
assert pred == 0, f'Expected setosa (0) but got {pred}'
print('Sanity test PASSED — model predicts setosa correctly.')Verificação rápida
Teste sua compreensão sobre como salvar e carregar fluxos nesta lição.
Recapitulação da lição
Nesta lição, você aprendeu que joblib.dump e joblib.load salvam e restauram um pipeline ajustado completo, incluindo todos os parâmetros de pré-processamento; que é importante sempre registrar as versões das bibliotecas junto com o modelo salvo para garantir um carregamento reproduzível; e que você deve nunca carregar arquivos pickle de fontes não confiáveis, pois eles podem executar código arbitrário. A seguir, abordaremos conjuntos de dados desbalanceados: como detectar o desbalanceamento entre classes e entender por que a acurácia é uma métrica enganosa nesse contexto.
Aprenda Python com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 30
- Aulas
- 120
Perguntas Frequentes
A aula “Salvamento e carregamento de um Pipeline com joblib” é grátis?
Sim — o texto completo de “Salvamento e carregamento de um Pipeline com joblib” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Machine Learning Academy, atualize para CoddyKit PRO. O curso de Machine Learning Academy inclui 4 aulas no total.
O que vou aprender em “Salvamento e carregamento de um Pipeline com joblib”?
Os alunos serializarão um Pipeline ajustado em disco com joblib.dump e o recarregarão em uma nova sessão do Python para fazer previsões sem treinar novamente. Você pratica Machine Learning Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Machine Learning Academy?
Nenhuma experiência prévia é necessária. Machine Learning Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Salvamento e carregamento de um Pipeline com joblib”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Machine Learning Academy?
Sim. Cada aula de Machine Learning Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Criação do primeiro Pipeline: escalonador e classificador
- ColumnTransformer dentro de um Pipeline
- Validação cruzada e busca em grade de um Pipeline completo
- Salvamento e carregamento de um Pipeline com joblib