Olá! Meu nome é Fabrício Zilli, serei o instrutor nas próximas aulas do curso de Kubeflow da Alura, conduzindo ao mundo de construção de pipelines (fluxos de processamento) dentro do Kubernetes, utilizando o Kubeflow.
Audiodescrição: Sou um homem branco, com cabelo curto, barba curta e visto um moletom marrom. Atrás de mim há uma parede branca, com uma estante a um lado, algumas luzes e uma planta.
Neste curso, percorreremos todo o ciclo de vida de construção de um modelo de aprendizado de máquina, utilizando componentes do Kubernetes.
Na primeira aula, compreenderemos por que utilizar Kubernetes para modelos de aprendizado de máquina.
Neste projeto, realizaremos a análise exploratória de dados utilizando o Jupyter Notebook, executando-o em nosso cluster de Kubernetes.
Em seguida, veremos nosso primeiro componente do Kubeflow, o KFP (Kubeflow Pipelines), que é um componente voltado à criação de pipelines (fluxos de processamento).
Depois, estudaremos o Katib, outro componente do Kubeflow, voltado à otimização de hiperparâmetros.
Por fim, treinaremos nosso modelo com o Kubeflow Training Operator e disponibilizaremos esse modelo, expondo-o por meio de uma API (interface de programação de aplicações), utilizando o KServe.
Ao longo de todo o curso, utilizaremos um projeto como guia, focado em detecção de fraude. Trabalharemos com um conjunto de dados contendo diversos registros de transações de cartão de crédito e treinaremos um modelo para identificar se determinada transação é fraude ou não.
Eu espero você na próxima aula.
Primeiro, precisamos entender por que discutimos Kubernetes em projetos de aprendizado de máquina.
Quem já trabalhou ou vai trabalhar com aprendizado de máquina provavelmente já passou ou passará por situações como estas:
Todos esses problemas convergem para três dores principais: reprodutibilidade, escalabilidade e resiliência.
A primeira solução que costuma vir à mente para esses problemas é utilizar contêineres. De fato, contêineres resolvem a questão da reprodutibilidade, mas não resolvem os problemas de escalabilidade nem de resiliência.
A reprodutibilidade se resolve porque, com contêineres, nós empacotamos todo o nosso código, variáveis de ambiente e bibliotecas, de forma que possamos enviar esse pacote para qualquer outro dispositivo ou equipamento e obter o mesmo resultado que obtivemos, por exemplo, na nossa máquina.
No entanto, isso não resolverá a questão da escalabilidade nem da resiliência. É nesse ponto que entra o Kubernetes. O Kubernetes funcionará como um grande orquestrador que gerenciará nossos contêineres, quaisquer que sejam, e garantirá que possam ser executados, que sejam recriados se algum deles apresentar falha e, inclusive, que a máquina onde esses contêineres estão sendo executados possa ser escalada. É ele quem desempenhará esse papel de mestre e orquestrará todos esses contêineres e as capacidades que temos.
O Kubernetes é declarativo. Nós não precisamos nos preocupar em definir e arquitetar toda essa estrutura; simplesmente declaramos como queremos que nosso cluster (agrupamento) seja e se comporte. Definimos, por exemplo, que queremos N réplicas desses contêineres, que esses contêineres tenham à disposição uma determinada quantidade de memória RAM e que estejam conectados a determinados serviços. O Kubernetes garantirá e trabalhará de forma contínua para que todas essas definições sejam respeitadas e estejam em vigor dentro do nosso cluster (agrupamento).
O Kubernetes garantirá que nossos contêineres sejam executados quando desejarmos e que nossas máquinas sejam instanciadas com a quantidade de recursos exigidos e necessários para que funcionem. Se algum contêiner ou outro tipo de componente precisar de mais recursos, o Kubernetes se encarregará de oferecer e garantir que esse contêiner tenha o recurso necessário. Se algum contêiner falhar, o Kubernetes o recriará e garantirá que sempre mantenhamos o estado que declaramos anteriormente para nosso cluster (agrupamento).
E o Kubeflow? O Kubeflow é construído sobre o Kubernetes; na prática, fornece novos componentes para essa infraestrutura no Kubernetes, porém focados em problemas de aprendizado de máquina. Como o Kubernetes é genérico, o Kubeflow é específico para esses problemas. O vocabulário e as aplicações se voltam a problemas de aprendizado de máquina e não necessariamente à infraestrutura. Mantém total compatibilidade com o Kubernetes, mas oferece módulos e soluções para desafios que enfrentamos em projetos de aprendizado de máquina, como treinar modelos, servir modelos ou criar pipelines (fluxos de processamento).
É isso que veremos durante este curso.
Nesta aula, vamos discutir alguns conceitos e componentes essenciais quando falamos de Kubernetes e que são fundamentais para utilizar no Kubeflow. Os componentes que vamos tratar nesta aula são os Pods (Pods), o Deployment (implantação), os Jobs (tarefas), os Namespaces (espaços de nomes), Requests (solicitações), Limits (limites) e os CRDs (definições de recursos personalizados).
O primeiro tema são os Pods (Pods). Os Pods são a menor unidade de Kubernetes. Podemos pensá-los como “envelopes” onde colocamos contêineres, podendo haver um ou mais contêineres dentro de um mesmo Pod. Todos os contêineres no mesmo Pod compartilham a mesma rede e o mesmo volume, sendo iniciados e encerrados conjuntamente. Na prática, geralmente encontramos um único contêiner por Pod; no entanto, podem existir casos com dois, três ou mais contêineres.
Na tela, vemos um exemplo de um arquivo YAML. Já comentamos que Kubernetes é declarativo. Declaramos o estado desejado sempre por meio de arquivos YAML, que seguem uma estrutura muito semelhante à exibida. Nesse exemplo, temos apiVersion, kind, metadata e spec. É importante memorizar esses nomes, porque cada elemento de Kubernetes segue esse mesmo formato. O campo kind informa o tipo — neste caso, Pod. O metadata identifica o componente, e o spec descreve o estado esperado desse componente.
Para ilustrar essa estrutura, veja um Pod definido em YAML, com apiVersion, kind, metadata e spec, contendo um contêiner de exemplo:
apiVersion: v1
kind: Pod
metadata:
name: dataset-loader
namespace: kubeflow
spec:
containers:
- name: loader
image: busybox:1.37
Esse exemplo mostra um Pod simples no namespace kubeflow, com um único contêiner usando a imagem busybox. Como comentamos, todos os contêineres de um Pod compartilham rede e volumes e são gerenciados em conjunto.
Há, entretanto, um problema: quando usamos somente o Pod, se ele por acaso cair, o Kubernetes não o recriará. Quando precisamos manter contêineres ativos ou estabelecer alguma regra pela qual esses contêineres devem executar até certo ponto, utilizamos Deployments (implantações) e Jobs (tarefas).
Ao falarmos de Deployment, definimos que esse componente deve permanecer sempre ativo, sempre em execução. Novamente, especificamos o comportamento por meio de arquivos YAML, como no exemplo em tela. Continuamos com as chaves kind, metadata e spec, mas com algumas diferenças. Em kind, indicamos Deployment. Em spec, definimos, por exemplo, quantas réplicas do contêiner que indicamos em template desejamos manter em execução. Nesse Deployment, temos replicas igual a 1. Isso significa que o Kubernetes garantirá que ao menos uma réplica desse contêiner — neste caso, um Jupyter Notebook, um Jupyter Server — esteja em execução no nosso cluster. Se, por acaso, o Pod cair, o Kubernetes garantirá que uma nova réplica, isto é, uma nova instância desse contêiner, seja criada e volte a atender no cluster.
Um exemplo de Deployment que mantém um Jupyter Server sempre disponível, com uma réplica, fica assim:
apiVersion: apps/v1
kind: Deployment
metadata:
name: jupyter
namespace: kubeflow
spec:
replicas: 1
selector:
matchLabels:
app: jupyter
template:
metadata:
labels:
app: jupyter
spec:
containers:
- name: jupyter
image: quay.io/jupyter/scipy-notebook:latest
Observe que definimos replicas: 1 e descrevemos o Pod template dentro de spec.template, garantindo que o Kubernetes recrie a instância caso ela falhe.
Diferentemente do Deployment, outro tipo de componente é o Job. O Job executa o contêiner até a conclusão, que pode ser bem-sucedida ou com falha. No YAML que define o comportamento desse componente, há a chave backoffLimit. Esse backoffLimit é a quantidade de vezes que o Job tentará se executar novamente em caso de falha. A chave restartPolicy indica que, se ocorrer uma falha, o contêiner deve ser reiniciado; e quantas vezes isso ocorrerá seguirá exatamente a quantidade configurada em backoffLimit.
Veja um exemplo de Job configurado para tentar novamente até três vezes em caso de falha, reiniciando o contêiner quando necessário:
apiVersion: batch/v1
kind: Job
metadata:
name: train-fraude
namespace: kubeflow
spec:
backoffLimit: 3
template:
spec:
restartPolicy: OnFailure
containers:
- name: trainer
image: fraude-trainer:2.0
args: ["--segment=low"]
Portanto, em Kubernetes, definimos tudo de forma declarativa.
Declaramos que queremos que esse contêiner seja executado: ele vai iniciar, executar o que for necessário e finalizar. Se, por acaso, encerrar com falha, vamos reiniciá-lo e tentar executar novamente, até um limite de três vezes.
Quando costumamos usar Job e quando costumamos usar Deployment? Ou, ainda, quando utilizaremos um Pod? Utilizaremos Jobs quando tivermos alguma situação em que queremos que o contêiner inicie e pare por si só. Exemplos: casos de treinamento de modelo, nos quais vamos treinar o modelo, concluir o treinamento e encerrar; realizar algum tipo de processamento de dados, como o que faremos nas pipelines (fluxos de processamento); ou executar a otimização de hiperparâmetros, percorrendo e realizando experimentos em busca dos melhores hiperparâmetros para determinado modelo. Em todos esses cenários, há começo, meio e fim. Para esses casos, utilizaremos Jobs.
Agora, quando quisermos um serviço que esteja sempre online, sempre disponível para ser acessado e utilizado, como no caso de um servidor para Jupyter Notebooks ou mesmo uma página de inferência, utilizaremos o componente do tipo Deployment.
Quanto aos Pods, como comentamos, raramente os utilizamos. Geralmente, vamos utilizar Jobs ou Deployments. Os Pods ficam para casos muito específicos, como Pods temporários, quando precisamos iniciar um contêiner por um curto período de tempo.
Outra característica dos nossos ambientes são os Namespaces. Podemos pensar neles como uma pasta lógica, isto é, uma forma de organizar os recursos dos nossos clusters de Kubernetes. Assim, todos os componentes que criarmos estarão dentro de algum Namespace. Dessa forma, podemos filtrar e gerenciar esses componentes à medida que formos instanciando novos.
Para exemplificar, a definição de um Namespace chamado kubeflow pode ser feita assim:
apiVersion: v1
kind: Namespace
metadata:
name: kubeflow
labels:
pod-security.kubernetes.io/enforce: privileged
Outra característica muito importante em Kubernetes são os recursos. Eles definem quantos recursos de computação o contêiner, o Deployment ou o Job terão disponíveis para execução. Quando utilizamos a chave requests, definimos o mínimo garantido. No exemplo apresentado, cpu: 1 e memory: 2Gi significam que esse contêiner, Deployment ou Job terá, no mínimo, 1 CPU de processamento e 2 GB de RAM disponíveis. Já limits definem o máximo. No exemplo, cpu: 2 e memory: 4Gi indicam que, como mínimo, teremos 1 CPU e, como máximo, 2; como mínimo, 2 GB de memória e, como máximo, 4 GB. Se, por acaso, a memória ultrapassar 4 GB, o contêiner (ou recurso) apresentará o erro out of memory (falta de memória) e provavelmente será interrompido. Em seguida, o Kubernetes iniciará novamente o componente.
No YAML, esses recursos são especificados na seção resources do contêiner (por exemplo, dentro de spec.template.spec.containers em um Deployment ou em um Job), como no trecho abaixo:
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
Por fim, temos os CRDs, que são as Custom Resource Definitions (Definições Personalizadas de Recursos). Esse é um mecanismo que o Kubernetes oferece para permitir a criação de novos tipos de componentes do Kubernetes. Pods, Jobs e Deployments são incorporados por padrão, ou seja, já vêm no Kubernetes. Todos os demais componentes que utilizaremos no Kubeflow são criados por meio de CRDs. Não precisamos nos preocupar, pois não vamos criar novos CRDs. No entanto, é importante entendermos como o Kubeflow permite novos componentes sobre o Kubernetes — e isso ocorre por meio dos CRDs.
[♪]
O curso Kubeflow: construindo pipelines de machine learning em produção possui 294 minutos de vídeos, em um total de 57 atividades. Gostou? Conheça nossos outros cursos de MLOps e Operacionalização em Dados, ou leia nossos artigos de Dados.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
O Plano Plus evoluiu: agora com Luri para impulsionar sua carreira com os melhores cursos e acesso à maior comunidade tech.
2 anos de Alura
Matricule-se no plano PLUS 24 e garanta:
Jornada de estudos progressiva que te guia desde os fundamentos até a atuação prática. Você acompanha sua evolução, entende os próximos passos e se aprofunda nos conteúdos com quem é referência no mercado.
Back-end, Dados, Front-end, DevOps, Mobile, Gestão & Negócios, UX & Design, Cibersegurança, Cloud, Inteligência Artificial
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
Acesso à inteligência artificial da Alura.
No Discord, você participa de eventos exclusivos, pode tirar dúvidas em estudos colaborativos e ainda conta com mentorias em grupo com especialistas de diversas áreas.
Catálogo de tecnologia para quem é da área de Marketing
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
20% de desconto na Pós Tech
Luri Vision chegou no Plano Pro: a IA da Alura que enxerga suas dúvidas, acelera seu aprendizado e conta também com o Alura Língua que prepara você para competir no mercado internacional.
2 anos de Alura
Todos os benefícios do PLUS 24 e mais vantagens exclusivas:
Acesso ao catálogo da Casa do Código e leitura dentro da plataforma
Chat, busca, exercícios abertos, revisão de aula, geração de legenda para certificado.
Modo entrevista - Pratique situações reais e evolua com feedback personalizado
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Para quem quer atingir seus objetivos mais rápido: Luri Vision ilimitado, vagas de emprego exclusivas e mentorias para acelerar cada etapa da jornada.
2 anos de Alura
Todos os benefícios do PRO 24 e mais vantagens exclusivas:
Lives CareerUp: eventos exclusivos com foco em empregabilidade e carreira
Mentorias de carreira: 2 encontros individuais com mentores do Talent Lab
Conecte-se ao mercado com mentoria individual personalizada, vagas exclusivas e networking estratégico que impulsionam sua carreira tech para o próximo nível.