Curso
Integração Contínua (CI) e Deploy Contínuo (CD) são práticas comuns no desenvolvimento de software para automatizar a integração de mudanças de código, testá-las e publicar rapidamente a aplicação atualizada. Inicialmente, essas práticas foram criadas para aplicativos tradicionais, mas hoje são cada vez mais relevantes em projetos de machine learning (ML).
Neste guia completo, vamos explorar CI/CD para ML e aprender a construir nossa própria pipeline de machine learning para automatizar o treinamento, a avaliação e o deploy do modelo.
Este guia apresenta um projeto simples que usa apenas GitHub Actions para automatizar todo o processo. A maior parte do que vamos discutir já é conhecida por engenheiros de machine learning e cientistas de dados. O que você vai aprender aqui é como usar GitHub Actions, Makefile, CML e Hugging Face CLI.
Inscreva-se no curso MLOps Concepts para aprender a levar modelos de machine learning de notebooks locais para produção, gerando valor de negócio.
Por que CI/CD para machine learning?
CI/CD muda o jogo quando o assunto é operacionalizar seu modelo e usá-lo em um produto. Ao simplificar a automação, você ganha uma solução rápida, escalável e sem bugs para seu projeto de ML, permitindo focar em melhorar o modelo em vez de gerenciar e fazer deploy da solução.
Em especial, CI/CD para machine learning ajuda em:
1. Automação da pipeline de treinamento
Com CI/CD, você pode re-treinar seus modelos automaticamente em dados novos, em uma agenda regular, economizando tempo em relação a disparar o re-treinamento manualmente.
2. Detecção precoce de erros
Ferramentas de CI executam testes e checagens a cada commit, ajudando a capturar bugs, problemas de integração e quedas de performance do modelo.
3. Reprodutibilidade
CI/CD garante que modelos possam ser reconstruídos e re-treinados exatamente do mesmo jeito, permitindo reproduzir resultados. Ambientes, versionamento de modelos e dados e configurações ficam codificados.
4. Testes e monitoramento
CI/CD permite testar automaticamente novos modelos antes do deploy para verificar possíveis issues. Ele também facilita o monitoramento pós-deploy por meio da integração com ferramentas de observabilidade.
5. Iteração mais rápida
Novas versões de modelos ou experimentos podem ser treinados, testados e publicados rapidamente de forma automatizada com CI/CD, acelerando o desenvolvimento e a melhoria de sistemas de ML.
6. Escalabilidade
À medida que o projeto de ML cresce em tamanho e complexidade, gerenciar manualmente todo o ciclo de vida se torna inviável. Pipelines de CI/CD oferecem uma solução escalável que lida com grandes volumes de dados, inúmeros modelos e diversas dependências, mantendo eficiência e confiabilidade.
Descrição do projeto
Neste guia, vamos mostrar como configurar contas e ambientes, criar uma pipeline de CI/CD e otimizar todo o processo.
Vamos usar pipelines do scikit-learn para treinar um algoritmo de random forest e construir um classificador de medicamentos. Depois do treinamento, vamos automatizar a avaliação com CML. Por fim, vamos construir e publicar o app web no Hugging Face Hub.
Do treinamento à avaliação, todo o processo será automatizado com GitHub Actions. Tudo o que você precisa fazer é dar push no código para o seu repositório no GitHub e, em até dois minutos, o modelo será atualizado no Hugging Face com o app, o modelo e os resultados mais recentes.

Se quiser aprender mais com exercícios interativos, faça o curso da DataCamp CI/CD for Machine Learning e leve seu desenvolvimento em ML a outro nível com GitHub Actions e Data Version Control.
Configuração inicial
Nesta seção, vamos criar um repositório no GitHub, os arquivos e pastas necessários e um Space no Hugging Face.
Repositório GitHub
Clique no botão “+” no canto superior direito da página inicial do GitHub e selecione “New repository”.
Adicione o nome e a descrição do repositório, marque a opção de criar o README e defina o .gitignore como Python.

Depois de criar o repositório, copie a URL. Em seguida, abra o terminal ou bash e navegue até o diretório onde você quer guardar a pasta do projeto.
Por fim, clone o repositório executando o seguinte comando:
git clone https://github.com/kingabzpro/CICD-for-Machine-Learning.git
Para começar, use a sua IDE favorita para abrir o repositório local. Recomendamos usar o VSCode neste projeto. Ao abrir a IDE, você verá o workspace do VSCode com arquivos como README e LICENSE.
Hugging Face Spaces
Vamos criar um Hugging Face Space que usaremos para fazer o deploy da nossa aplicação junto com o arquivo do modelo.
1. Clique na sua foto de perfil e selecione "New Space".

2. Adicione o nome do Space, a licença, o tipo de SDK e clique em Create Space.

3. Para editar o arquivo README.md, clique nos três pontos no canto superior esquerdo, selecione Files e faça as alterações necessárias.

4. Vamos copiar os metadados do README do Space e colar no nosso README local que ficará na pasta App.
Arquivos essenciais
Precisamos criar as pastas e arquivos necessários antes de começar a experimentar e construir as pipelines. Isso vai nos ajudar a manter o workspace organizado a longo prazo.
Crie as pastas
- App: para adicionar o arquivo do classificador web, o README do app com metadados e o requirement.txt para instalar os pacotes necessários.
- Data: para todos os nossos arquivos CSV.
- Model: para arquivos de modelos treinados.
- Results: para salvar métricas e resultados em arquivos PNG.
Pasta App
Crie um arquivo Python chamado drug_app.py, junto com um README.md e um requirements.txt, e mova todos para a pasta App. Assim, organizamos melhor os arquivos necessários para rodar o app.
Em seguida, edite o README.md da pasta App e garanta que o versionamento dos metadados foi ajustado. Assim, você consegue apontar facilmente para a localização dos arquivos do app, mudar cores, definir a versão do SDK e adicionar informações de licença.
---
title: Drug Classification
emoji: 💊
colorFrom: yellow
colorTo: red
sdk: gradio
sdk_version: 4.16.0
app_file: drug_app.py
pinned: false
license: apache-2.0
---
Edite o requirement.txt na pasta App adicionando os pacotes Python ausentes:
scikit-learn
skops
Observação: os arquivos requirement e README serão diferentes no repositório do GitHub e no Hugging Face Space.
Pasta Data
Baixe o dataset Drug Classification no Kaggle, extraia o arquivo CSV e mova-o para a pasta Data.
Pastas Model e Results
As pastas Model e Results ficarão vazias, pois serão preenchidas pelo script Python que vamos rodar.
Arquivos do repositório
- Crie um
Makefilepara simplificar a execução do script no workflow do GitHub Actions. - Crie um Jupyter Notebook chamado
notebook.ipynb. Nele, vamos experimentar com algoritmos e pipelines de processamento. - Crie um arquivo
requirements.txt. Ele será usado para configurar o ambiente durante os jobs do workflow de CI. - Crie um arquivo
train.py. Ele terá o código Python para carregar e processar dados, além de treinar, avaliar e salvar o modelo e as métricas de performance.
Nossa estrutura de diretórios deve ficar assim:

Treinando e avaliando o modelo de classificação de medicamentos
Nesta parte, vamos criar o código Python que processa os dados e treina um modelo usando uma pipeline do scikit-learn. Em seguida, vamos avaliar e salvar os resultados e o modelo.
Carregando o dataset
Vamos usar pandas para carregar o CSV, embaralhá-lo com a função sample e exibir as três primeiras linhas.
import pandas as pd
drug_df = pd.read_csv("Data/drug.csv")
drug_df = drug_df.sample(frac=1)
drug_df.head(3)

Separando treino e teste
Crie a variável dependente e as independentes. Em seguida, divida em conjuntos de treinamento e teste. Isso ajuda a avaliar o desempenho do modelo.
from sklearn.model_selection import train_test_split
X = drug_df.drop("Drug", axis=1).values
y = drug_df.Drug.values
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=125
)
Pipelines de machine learning
Vamos construir uma pipeline de processamento com ColumnTransformer, que vai converter valores categóricos em números, preencher valores ausentes e padronizar as colunas numéricas.
Depois, criaremos uma pipeline de treinamento que recebe os dados transformados e treina um classificador de random forest.
Por fim, vamos treinar o modelo.
Usando pipelines, garantimos reprodutibilidade, modularidade e clareza no código.
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OrdinalEncoder, StandardScaler
cat_col = [1,2,3]
num_col = [0,4]
transform = ColumnTransformer(
[
("encoder", OrdinalEncoder(), cat_col),
("num_imputer", SimpleImputer(strategy="median"), num_col),
("num_scaler", StandardScaler(), num_col),
]
)
pipe = Pipeline(
steps=[
("preprocessing", transform),
("model", RandomForestClassifier(n_estimators=100, random_state=125)),
]
)
pipe.fit(X_train, y_train)

Avaliação do modelo
Avalie o desempenho do modelo calculando a acurácia e o F1-score.
from sklearn.metrics import accuracy_score, f1_score
predictions = pipe.predict(X_test)
accuracy = accuracy_score(y_test, predictions)
f1 = f1_score(y_test, predictions, average="macro")
print("Accuracy:", str(round(accuracy, 2) * 100) + "%", "F1:", round(f1, 2))
Nosso modelo teve um desempenho excelente.
Accuracy: 95.0% F1: 0.91
Crie o arquivo de métricas e salve na pasta Results.
with open("Results/metrics.txt", "w") as outfile:
outfile.write(f"\nAccuracy = {accuracy.round(2)}, F1 Score = {f1.round(2)}.")
Em seguida, vamos criar a matriz de confusão e salvar a imagem na pasta Results.
import matplotlib.pyplot as plt
from sklearn.metrics import ConfusionMatrixDisplay, confusion_matrix
cm = confusion_matrix(y_test, predictions, labels=pipe.classes_)
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=pipe.classes_)
disp.plot()
plt.savefig("Results/model_results.png", dpi=120)

Salvando o modelo
Agora vamos salvar nosso modelo usando o pacote Python skops. Assim salvamos tanto a pipeline do scikit-learn quanto o modelo.
import skops.io as sio
sio.dump(pipe, "Model/drug_pipeline.skops")
Você pode carregar a pipeline inteira e ela funcionará direto, sem precisar processar os dados ou editar o código.
sio.load("Model/drug_pipeline.skops", trusted=True)

Copie e cole todo o código no arquivo 'train.py'. Este será o script de treinamento padronizado que rodará no workflow de CI sempre que houver mudança nos dados ou no código.
Antes de começar sua carreira em MLOps, leia o MLOps Roadmap: A Complete Career Guide.
Passos para construir sua pipeline de integração contínua
Nesta seção, vamos abordar CML, Makefile e a configuração de workflows do GitHub Actions para automatizar o treinamento, a avaliação e o versionamento do projeto.

Pipeline de CI
CML
Continuous Machine Learning (CML) é uma biblioteca open-source que permite implementar integração contínua em projetos de machine learning. Vamos usar a GitHub Action "iterative/setup-cml", que utiliza funções do CML no workflow para automatizar a geração do relatório de avaliação do modelo.
O que isso significa? Sempre que você der push no GitHub, ele vai gerar um relatório no commit e enviar um e-mail com as métricas de performance e a matriz de confusão.
Makefile
Um Makefile é um arquivo com um conjunto de instruções usado pelo comando make para automatizar tarefas como compilar código, rodar testes, configurar ambientes, pré-processar dados, treinar e avaliar modelos e fazer deploy.
Podemos usar comandos make para rodar múltiplos scripts e manter o arquivo do workflow de CI limpo e simples. O Makefile reúne nomes de conjuntos de comandos e os scripts que executam essas ações.
Aqui está o nosso Makefile:
install:
pip install --upgrade pip &&\
pip install -r requirements.txt
format:
black *.py
train:
python train.py
eval:
echo "## Model Metrics" > report.md
cat ./Results/metrics.txt >> report.md
echo '\n## Confusion Matrix Plot' >> report.md
echo '' >> report.md
cml comment create report.md
Temos comandos para instalar pacotes Python (install), formatar código (format), treinar scripts (train) e gerar relatórios do CML (eval).

Depois disso, vamos adicionar as mudanças, criar um commit e dar push das alterações para o servidor remoto do GitHub.
git commit -am "new changes"
git push origin main
GitHub Actions
Para automatizar o treinamento e a avaliação, precisamos criar um workflow do GitHub Actions. Para isso, vá até a aba “Actions” no repositório kingabzpro/CICD-for-Machine-Learning e clique no link azul “set up a workflow yourself.”

Renomeie o arquivo .yml para “ci” e comece a adicionar os comandos do GitHub Actions.
- Adicione o nome do workflow.
- Defina o gatilho para que o workflow rode em push ou pull request para a branch main, ou em execução manual.
- Crie o ambiente para o job. Vamos usar a última versão do Linux.
- Ative as GitHub Actions que serão usadas no workflow.
- Adicione as etapas de execução usando diferentes comandos make.
- Dispare o workflow com um commit. O GitHub Actions executará todas as etapas da pipeline em sequência.

Você vai se deparar com falhas enquanto ajusta erros e sintaxe. Por isso, é importante ler a sintaxe de workflow do GitHub Actions antes de mergulhar de cabeça.

Corrigimos com sucesso todos os erros e problemas do workflow e agora temos a versão final do arquivo `ci.yml` rodando sem problemas.
Como você pode ver, o workflow primeiro configura o ambiente e carrega as actions necessárias. Depois, executamos cada etapa usando o comando make, que chama vários scripts Python e Bash em segundo plano.
No entanto, há dois pontos importantes ao trabalhar com ações do CML. Primeiro, precisamos definir a permissão de escrita no início. Segundo, fornecer um token do GitHub para o job do CML, o que pode ser feito via secrets.
name: Continuous Integration
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch:
permissions: write-all
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: iterative/setup-cml@v2
- name: Install Packages
run: make install
- name: Format
run: make format
- name: Train
run: make train
- name: Evaluation
env:
REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: make eval
As métricas e resultados aparecem no commit.

Você também receberá um e-mail com os resultados.

Salvando os resultados em uma nova branch
Estamos gerando o relatório de avaliação, mas ainda não estamos versionando o modelo e os resultados. Para salvar as mudanças, vamos criar uma nova branch chamada "update" e enviar para ela o modelo e os resultados atualizados.
Crie a branch "update" clicando no botão da branch main, digitando "update" no nome e selecionando "create branch update from main".

Criando secrets do repositório
Para fazer commit e push via comandos Git, precisamos informar um nome de usuário e e-mail. Você pode adicioná-los diretamente, mas usar secrets do GitHub é a melhor opção. Siga estes passos:
- Vá em Settings e clique em "Secrets and variables".
- Selecione "Actions" e clique no botão verde "New repository secret".
- Adicione o nome e os valores. É como configurar uma variável de ambiente na sua máquina local.
Pronto!

Atualizando Makefile e ci.yml
Para automatizar o salvamento das mudanças na nova branch, precisamos atualizar o Makefile e o ci.yml.
Makefile:
Estamos configurando usuário e e-mail, fazendo commit das alterações e salvando na branch update.
update-branch:
git config --global user.name $(USER_NAME)
git config --global user.email $(USER_EMAIL)
git commit -am "Update with new results"
git push --force origin HEAD:update
ci.yml:
O Makefile usa variáveis de ambiente para rodar o script. Para isso, primeiro extraímos os valores dos secrets e, depois, passamos as variáveis de ambiente ao final do comando make.
- name: Update Branch
env:
NAME: ${{ secrets.USER_NAME }}
EMAIL: ${{ secrets.USER_EMAIL }}
run: make update-branch USER_NAME=$NAME USER_EMAIL=$EMAIL
Depois de atualizar os arquivos e dar push para a main, você verá tudo acontecendo em tempo real. Um relatório analítico será gerado, junto com um modelo atualizado que poderá ser publicado no Hugging Face na parte de deploy contínuo.
Passos para construir sua pipeline de deploy contínuo
Na seção de Deploy Contínuo, vamos automatizar o processo de publicar tanto o modelo quanto a aplicação. Isso envolve puxar o modelo e o arquivo do app atualizados da branch `update`, fazer login no Hugging Face CLI com um token, enviar os arquivos do modelo e do app e, por fim, fazer o deploy da aplicação.

Construa o app em Gradio
Para publicar nosso modelo e acessá-lo, precisamos criar um app em Gradio. Este app vai incluir:
- Carregar a pipeline do scikit-learn e o modelo.
- Uma função Python para prever o rótulo do medicamento a partir dos inputs do usuário.
- Criar uma interface de entrada com sliders do Gradio para valores float e radio do Gradio para valores categóricos.
- Criar exemplos de entrada para testar o modelo com facilidade.
- Fornecer o título do aplicativo, uma breve descrição de seus recursos e um rodapé com informações relevantes.
- Passar todas essas variáveis e a função de predição para a função
Interfacedo Gradio e lançar o app. - Para dar um visual moderno, vamos usar o tema soft padrão.
import gradio as gr
import skops.io as sio
pipe = sio.load("./Model/drug_pipeline.skops", trusted=True)
def predict_drug(age, sex, blood_pressure, cholesterol, na_to_k_ratio):
""Predict drugs based on patient features.
Args:
age (int): Age of patient
sex (str): Sex of patient
blood_pressure (str): Blood pressure level
cholesterol (str): Cholesterol level
na_to_k_ratio (float): Ratio of sodium to potassium in blood
Returns:
str: Predicted drug label
"""
features = [age, sex, blood_pressure, cholesterol, na_to_k_ratio]
predicted_drug = pipe.predict([features])[0]
label = f"Predicted Drug: {predicted_drug}"
return label
inputs = [
gr.Slider(15, 74, step=1, label="Age"),
gr.Radio(["M", "F"], label="Sex"),
gr.Radio(["HIGH", "LOW", "NORMAL"], label="Blood Pressure"),
gr.Radio(["HIGH", "NORMAL"], label="Cholesterol"),
gr.Slider(6.2, 38.2, step=0.1, label="Na_to_K"),
]
outputs = [gr.Label(num_top_classes=5)]
examples = [
[30, "M", "HIGH", "NORMAL", 15.4],
[35, "F", "LOW", "NORMAL", 8],
[50, "M", "HIGH", "HIGH", 34],
]
title = "Drug Classification"
description = "Enter the details to correctly identify Drug type?"
article = "This app is a part of the Beginner's Guide to CI/CD for Machine Learning. It teaches how to automate training, evaluation, and deployment of models to Hugging Face using GitHub Actions."
gr.Interface(
fn=predict_drug,
inputs=inputs,
outputs=outputs,
examples=examples,
title=title,
description=description,
article=article,
theme=gr.themes.Soft(),
).launch()
Abra o terminal e rode o app localmente para corrigir issues antes de enviar as mudanças para o repositório remoto.
python ./App/drug_app.py
Running on local URL: http://127.0.0.1:7860
To create a public link, set `share=True` in `launch()`.
Configurando o token do Hugging Face
Agora vamos gerar o token do Hugging Face e fornecê-lo ao nosso script do Makefile. Porém, precisamos garantir que o token fique confidencial e não vaze. Para isso, vamos usar os secrets do GitHub.
Primeiro, clique na sua foto de perfil no Hugging Face e selecione Settings. Depois, escolha "Access Tokens" e clique em "New Token" para gerar o token. Ao gerar, garanta que ele tenha permissão de escrita.

Copie o token e crie um secret no repositório, assim como fizemos com o nome de usuário e o e-mail.

Workflow de CD
Nesta seção, vamos adicionar três novos comandos para criar arquivos e configurar outro workflow no GitHub chamado "Continuous Deployment". Esse workflow vai automatizar o pull e o deploy dos arquivos.
Makefile
- Puxar o modelo e os arquivos de resultado atualizados da branch
updatee mudar para aupdate. - Antes do login, instalar o Hugging Face CLI e então fazer login com o token.
- Enviar a pasta App para o diretório base do Space, garantindo que tenha o Python, o README e o requirement.txt para montar o ambiente e rodar o app.
- Também vamos enviar as pastas Model e Results.
- O comando
deployexecutará primeiro ohf-logine depois opush-hub.
hf-login:
git pull origin update
git switch update
pip install -U "huggingface_hub[cli]"
huggingface-cli login --token $(HF) --add-to-git-credential
push-hub:
huggingface-cli upload kingabzpro/Drug-Classification ./App --repo-type=space --commit-message="Sync App files"
huggingface-cli upload kingabzpro/Drug-Classification ./Model /Model --repo-type=space --commit-message="Sync Model"
huggingface-cli upload kingabzpro/Drug-Classification ./Results /Metrics --repo-type=space --commit-message="Sync Model"
deploy: hf-login push-hub
Nosso app terá acesso ao modelo, ao arquivo da aplicação e aos resultados atualizados, permitindo rastrear mudanças no Space do Hugging Face.
cd.yml
Para termos um fluxo realmente CI/CD, precisamos criar outro arquivo chamado cd.yml, semelhante ao ci.yml. Assim que a pipeline de CI terminar, ela iniciará o workflow cd.yml usando o parâmetro on com workflow_run.
Esse workflow vai montar o ambiente e executar o comando make deploy usando o token do Hugging Face para publicar as últimas mudanças no Hugging Face Hub.
name: Continuous Deployment
on:
workflow_run:
workflows: ["Continuous Integration"]
types:
- completed
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deployment To Hugging Face
env:
HF: ${{ secrets.HF }}
run: make deploy HF=$HF
Quando enviarmos as mudanças para a branch main, o processo começa com o workflow de CI.

Após a conclusão do CI, o workflow de CD inicia, como mostrado abaixo.

É possível acompanhar os logs ao vivo de cada etapa selecionando a execução no build do workflow. Nossos arquivos foram enviados com sucesso para o servidor do Hugging Face.

Depois de receber os arquivos atualizados, o Hugging Face Space começa a montar o ambiente e o app entra no ar em poucos segundos.

Nossa aplicação de Drug Classification funciona perfeitamente e tem uma interface linda.
Experimente inserir diferentes dados para ver o desempenho do modelo na prática.

Imagem Fonte
Conclusão
Este guia mostrou como automatizamos os processos de treinamento, avaliação, versionamento e deploy, garantindo que qualquer mudança nos dados ou algoritmos acione esse fluxo automaticamente, sem erros. Essa abordagem ajuda a construir aplicações rápidas, escaláveis e prontas para produção.
Note que, em projetos reais, usamos várias ferramentas de MLOps para orquestrar, versionar, publicar e monitorar aplicações de machine learning. Para saber mais, confira as Top MLOps Tools You Need to Know, que destacam tecnologias populares usadas por grandes empresas para escalar aplicações de ML.
Para otimizar sua pipeline de CI/CD, é fundamental aprender ferramentas como Docker, Kubernetes, Azure Cloud e outras tecnologias de MLOps. Siga o tutorial Machine Learning, Pipelines, Deployment, and MLOps para conhecer práticas padrão do mercado e trabalhar em projetos avançados.
Recursos do projeto
- Repositório GitHub: kingabzpro/CICD-for-Machine-Learning
- Hugging Face Space: Drug Classification - um Hugging Face Space de kingabzpro
- Dataset no Kaggle: Drug Classification
Sou um cientista de dados certificado que gosta de criar aplicativos de aprendizado de máquina e escrever blogs sobre ciência de dados. No momento, estou me concentrando na criação e edição de conteúdo e no trabalho com modelos de linguagem de grande porte.


