Design de aplicativo para cargas de trabalho de IA no Azure
Há muitas opções disponíveis para você considerar ao planejar a criação de um aplicativo com funções de IA. Seus requisitos funcionais e não funcionais exclusivos ajudam a restringir as decisões de alto nível sobre seu design, como se o caso de uso é aprendizado de máquina tradicional, generativo, determinístico ou uma combinação de tipos de IA. À medida que você passa de áreas de design de alto nível para áreas de design de nível inferior, há várias opções a serem consideradas ao longo do caminho.
Conforme discutido no artigo Introdução , escolher se deseja criar seu próprio modelo ou usar um modelo predefinido é uma das primeiras decisões importantes a serem tomadas. Ao escolher um modelo predefinido, considere estes pontos:
Fontes de catálogo. Explore repositórios como o Hub de Modelo de Rosto Hugging, o Hub do TensorFlow ou o catálogo de modelos do Azure AI Studio para encontrar modelos pré-treinados. Essas plataformas fornecem um extenso catálogo de modelos em várias tarefas.
Licenciamento. Certifique-se de que os termos de licenciamento do modelo atendam às suas metas de segurança, conformidade e aplicativo, especialmente se você planeja distribuir o aplicativo ou integrá-lo a outros serviços.
Componentes-chave. Examine a arquitetura, os dados de treinamento, o desempenho e o licenciamento do modelo para determinar se ele está ajustado para sua tarefa ou domínio.
Para obter diretrizes sobre como escolher uma plataforma de hospedagem, consulte Considerações sobre a plataforma de hospedagem de modelo.
Este artigo explora muitas áreas comuns de design e fatores a serem considerados ao tomar decisões importantes sobre tecnologia e abordagem.
Recomendações
Aqui está o resumo das recomendações fornecidas neste artigo.
Recomendação | Descrição |
---|---|
Priorize soluções prontas para uso. | Sempre que possível, use soluções de PaaS (plataforma como serviço) para lidar com funções de carga de trabalho. Use modelos pré-criados e pré-treinados sempre que possível para minimizar a carga operacional e de desenvolvimento para suas equipes de carga de trabalho e operações. |
Funções e capacidades abstratas longe do cliente. | Mantenha o cliente o mais fino possível projetando serviços de back-end para lidar com preocupações transversais, como limitação de taxa e operações de failover. |
Bloqueie o acesso aos armazenamentos de dados. | O código no sistema de IA não deve tocar diretamente em seus armazenamentos de dados. Encaminhe todas as solicitações de dados por meio de uma camada de API. As APIs devem ser criadas especificamente para a tarefa específica necessária. |
Isole seus modelos. | Assim como os armazenamentos de dados, use uma camada de API para atuar como um gateway para solicitações ao modelo. Algumas soluções de PaaS, como o Azure OpenAI Service e o Azure Machine Learning, usam SDKs para essa finalidade. Muitas ferramentas, como o PromptFlow, contêm suporte nativo para propagar APIs para o serviço. |
Projete componentes para serem implantados de forma independente. | Modelos de IA, pipelines de dados, componentes de front-end e microsserviços, como pré-processamento de dados, extração de recursos e inferência, devem ser implantados de forma independente para otimizar a flexibilidade, a escalabilidade e a operabilidade de sua carga de trabalho. |
Componentes de conteinerização
Para garantir que seus componentes implantáveis de forma independente sejam totalmente independentes e para simplificar suas implantações, considere a conteinerização como parte de sua estratégia de design. Os seguintes componentes devem ser conteinerizados:
Microsserviços: microsserviços individuais que lidam com funções específicas do aplicativo, como processamento de dados, inferência de modelo ou autenticação de usuário, devem ser conteinerizados. Essa abordagem permite implantação e dimensionamento independentes, facilitando atualizações e manutenção mais eficientes.
Modelos de IA: conteinerize modelos de IA para garantir que todas as dependências, bibliotecas e configurações sejam agrupadas. Essa abordagem isola o ambiente de modelo do sistema host, evitando conflitos de versão e garantindo um comportamento consistente em diferentes ambientes de implantação.
Pipelines de processamento de dados: todas as tarefas de processamento de dados que precedem ou seguem a inferência do modelo, como limpeza, transformação e extração de recursos de dados, devem ser conteinerizadas. Essa abordagem aumenta a reprodutibilidade e simplifica o gerenciamento de dependências.
Serviços de infraestrutura: os serviços que fornecem suporte à infraestrutura, como bancos de dados ou camadas de cache, também podem se beneficiar da conteinerização. Essa abordagem ajuda a manter a consistência da versão e facilita o dimensionamento e o gerenciamento desses componentes.
Colocar componentes de IA com outros componentes de carga de trabalho
Há vários bons motivos para colocar seus componentes de IA com outros componentes de carga de trabalho, mas há compensações em fazer isso. Os motivos pelos quais você pode colocar são:
Sensibilidade à latência: coloque componentes de IA com outros serviços, como hospedagem de API, quando a baixa latência for importante. Por exemplo, se a inferência em tempo real for necessária para aprimorar a experiência do usuário, colocar modelos de IA próximos à API pode minimizar o tempo necessário para recuperar os resultados.
Proximidade de dados: quando os modelos de IA exigem acesso frequente a conjuntos de dados específicos, como um índice de pesquisa, a colocação desses componentes pode melhorar o desempenho e reduzir a sobrecarga da transferência de dados para processamento e inferência mais rápidos.
Utilização de recursos: se determinados componentes tiverem necessidades de recursos complementares, como CPU e memória, colocá-los pode otimizar o uso de recursos. Por exemplo, um modelo que requer computação significativa pode compartilhar recursos com um serviço que tem demandas mais baixas ao mesmo tempo.
Troca. Existem compensações com a colocação de componentes que devem ser consideradas. Você pode perder a capacidade de implantar ou dimensionar componentes de forma independente. Você também pode aumentar o risco de mau funcionamento aumentando o raio de explosão potencial de incidentes.
Avalie o uso de orquestradores em soluções de IA generativa
Um orquestrador gerencia o fluxo de trabalho coordenando a comunicação entre os diferentes componentes da solução de IA que, de outra forma, seriam difíceis de gerenciar em cargas de trabalho complexas. Recomendamos que você crie um orquestrador em seu design se sua carga de trabalho tiver qualquer uma das seguintes características:
Fluxos de trabalho complexos: o fluxo de trabalho envolve várias etapas, como pré-processamento, encadeamento de modelos ou pós-processamento.
Lógica condicional: as decisões precisam ser tomadas dinamicamente com base nas saídas do modelo, como rotear resultados para modelos diferentes.
Dimensionamento e gerenciamento de recursos: você precisa gerenciar a alocação de recursos para aplicativos de alto volume usando o dimensionamento de modelo com base na demanda.
Gerenciamento de estado: você precisa gerenciar o estado e a memória das interações do usuário.
Recuperação de dados: você precisa ser capaz de recuperar dados de aumento do índice.
Considerações sobre o uso de vários modelos
Quando sua carga de trabalho usa vários modelos, o uso de um orquestrador é essencial. O orquestrador é responsável por rotear dados e solicitações para o modelo apropriado com base no caso de uso. Planeje o fluxo de dados entre modelos, garantindo que as saídas de um modelo possam servir como entradas para outro. O planejamento pode envolver processos de transformação ou enriquecimento de dados.
Orquestração e agentes
Para cargas de trabalho de IA generativa, considere adotar uma abordagem baseada em agente, às vezes chamada de agente, em seu design para adicionar extensibilidade à sua orquestração. Os agentes referem-se à funcionalidade associada ao contexto, compartilhando muitas características de estilo de microsserviço que executam tarefas em conjunto com um orquestrador. O orquestrador pode anunciar tarefas para um pool de agentes ou os agentes podem registrar recursos com o orquestrador. Ambas as abordagens permitem que o orquestrador decida dinamicamente como dividir e rotear a consulta entre os agentes.
As abordagens agenciais são ideais quando você tem uma superfície de interface do usuário comum com vários recursos em evolução que podem ser conectados a essa experiência para adicionar mais habilidades e dados de base ao fluxo ao longo do tempo.
Para cargas de trabalho complexas com muitos agentes, é mais eficiente permitir que os agentes colaborem dinamicamente em vez de usar um orquestrador para dividir tarefas e atribuí-las.
A comunicação entre o orquestrador e os agentes deve seguir um padrão de fila de tópicos, em que os agentes são assinantes de um tópico e o orquestrador envia tarefas por meio de uma fila.
O uso de uma abordagem agêntica funciona melhor com um padrão de orquestração do que com um padrão de coreografia.
Para obter mais informações, consulte Considerações sobre a plataforma de orquestração.
Avaliar o uso de gateways de API
Os gateways de API, como o Gerenciamento de API do Azure, abstraem funções das APIs, o que separa as dependências entre o serviço solicitante e a API. Os gateways de API fornecem os seguintes benefícios para cargas de trabalho de IA:
Vários microsserviços: eles ajudam você a gerenciar vários endpoints de modelo de IA e você precisa aplicar políticas consistentes, como limitação de taxa e autenticação.
Gerenciamento de tráfego: eles ajudam você a gerenciar aplicativos de alto tráfego com eficiência, gerenciando solicitações, armazenando respostas em cache e distribuindo cargas.
Segurança: eles fornecem controle de acesso centralizado, registro e proteção contra ameaças para as APIs por trás do gateway.
Aproveite os padrões de design de aplicativos de IA
Existem vários padrões de design comuns que foram estabelecidos no setor para aplicativos de IA que você pode usar para simplificar seu design e implementação. Esses padrões de design incluem:
Agrupamento de modelos: esse padrão de design envolve a combinação de previsões de vários modelos para melhorar a precisão e a robustez, mitigando os pontos fracos de modelos individuais.
Arquitetura de microsserviços: separar componentes em serviços implantáveis de forma independente aumenta a escalabilidade e a capacidade de manutenção, permitindo que as equipes trabalhem em diferentes partes do aplicativo simultaneamente.
Arquitetura orientada a eventos: a utilização de eventos para acionar ações permite componentes desacoplados e processamento em tempo real, tornando o sistema mais responsivo e adaptável às mudanças de dados.
Padrão RAG e estratégias de agrupamento
O padrão de Geração Aumentada por Recuperação (RAG) combina modelos generativos com sistemas de recuperação, permitindo que o modelo acesse fontes de conhecimento externas para melhorar o contexto e a precisão. Consulte a série Projetando e desenvolvendo uma solução RAG para obter orientações detalhadas sobre esse padrão. Existem duas abordagens RAG:
Just-in-time: essa abordagem recupera informações relevantes dinamicamente no momento de uma solicitação, garantindo que os dados mais recentes sejam sempre usados. É benéfico em cenários que exigem contexto em tempo real, mas pode introduzir latência.
Pré-calculado (armazenado em cache): esse método envolve o armazenamento em cache dos resultados de recuperação, reduzindo os tempos de resposta ao fornecer dados pré-calculados. Ele é adequado para cenários de alta demanda em que dados consistentes podem ser armazenados, mas podem não refletir as informações mais atuais, levando a possíveis problemas de relevância.
Ao usar um padrão RAG, uma estratégia de agrupamento bem definida é fundamental para otimizar a eficiência do desempenho da carga de trabalho. Comece com as diretrizes fornecidas na série Projetando e desenvolvendo uma solução RAG. Recomendações adicionais a serem consideradas são:
Implemente uma estratégia de agrupamento dinâmico que ajuste o tamanho dos blocos com base no tipo de dados, na complexidade da consulta e nos requisitos do usuário. Isso pode aumentar a eficiência da recuperação e a preservação do contexto.
Incorpore loops de feedback para refinar estratégias de agrupamento com base em dados de desempenho.
Preserve a linhagem de dados para partes mantendo metadados e identificadores exclusivos que se vinculam à fonte de aterramento. A documentação clara da linhagem ajuda a garantir que os usuários entendam a origem dos dados, suas transformações e como eles contribuem para a saída.
Quando usar padrões de design
Considere usar esses padrões de design quando seu caso de uso atender a uma das condições:
Fluxos de trabalho complexos: ao lidar com fluxos de trabalho complexos ou interações entre vários modelos de IA, padrões como RAG ou microsserviços podem ajudar a gerenciar a complexidade e garantir uma comunicação clara entre os componentes.
Requisitos de escalabilidade: se a demanda em seu aplicativo flutuar, o uso de um padrão como microsserviços permite que componentes individuais sejam dimensionados de forma independente, acomodando cargas variadas sem afetar o desempenho geral do sistema.
Aplicativos orientados a dados: se seu aplicativo exigir tratamento extensivo de dados, uma arquitetura orientada a eventos pode fornecer capacidade de resposta em tempo real e processamento de dados eficiente.
Observação
Aplicativos menores ou POCs normalmente não se beneficiarão da adoção de um desses padrões de design e devem ser criados com um design simplista. Da mesma forma, se você tiver restrições de recursos (orçamento, tempo ou número de funcionários), usar um design simplista que possa ser refatorado posteriormente é uma abordagem melhor do que adotar um padrão de design complexo.
Escolha as estruturas e bibliotecas certas
A escolha de estruturas e bibliotecas está intimamente ligada ao design do aplicativo, impactando não apenas a arquitetura, mas também o desempenho, a escalabilidade e a capacidade de manutenção. Por outro lado, os requisitos de design podem limitar as escolhas de estrutura, criando uma interação dinâmica entre os dois. Por exemplo, o uso do SK (SDK do Kernel Semântico) geralmente incentiva um design baseado em microsserviços em que cada agente ou funcionalidade é encapsulado em seu próprio serviço. Os fatores a serem considerados ao escolher estruturas e bibliotecas são:
Requisitos do aplicativo: Os requisitos específicos do aplicativo, como processamento em tempo real ou processamento em lote, podem limitar a escolha da estrutura. Por exemplo, se o aplicativo exigir baixa latência, poderá ser necessária uma estrutura com recursos assíncronos.
Necessidades de integração: O design pode exigir integrações específicas com outros sistemas ou serviços. Se uma estrutura não der suporte aos protocolos ou formatos de dados necessários, poderá ser necessário reconsiderar o design ou selecionar uma estrutura diferente.
Experiência da equipe: o conjunto de habilidades da equipe de desenvolvimento pode limitar as escolhas da estrutura. Um design que depende de uma estrutura menos familiar pode levar a um aumento do tempo e da complexidade do desenvolvimento, levando à seleção de uma ferramenta mais familiar.
Projete uma estratégia para identidades, autorização e acesso
De modo geral, você deve abordar a identidade, a autorização e o acesso da mesma maneira que normalmente projeta aplicativos. Você deve usar um provedor de identidade, como o Microsoft Entra ID, para gerenciar essas áreas o máximo possível. No entanto, existem desafios únicos para muitos aplicativos de IA que precisam de consideração especial. A persistência de listas de controle de acesso (ACLs) por meio do sistema às vezes é desafiadora ou mesmo impossível sem a introdução de novos desenvolvimentos.
Examine as diretrizes encontradas na solução RAG multilocatário segura para saber como adicionar metadados de filtragem de segurança a documentos e partes. Esse corte pode ser baseado em grupos de segurança ou construções organizacionais semelhantes.
Considere os requisitos não funcionais
Você pode ter requisitos não funcionais para sua carga de trabalho que são desafiadores devido a fatores inerentes às tecnologias de IA. Os requisitos não funcionais comuns e seus desafios incluem:
Latência da inferência/tempo limite do modelo: os aplicativos de IA geralmente exigem respostas em tempo real ou quase em tempo real. Projetar para baixa latência é crucial, o que envolve a otimização da arquitetura do modelo, pipelines de processamento de dados e recursos de hardware. A implementação de estratégias de cache e a garantia de carregamento eficiente do modelo também são essenciais para evitar tempos limite e fornecer respostas oportunas.
Limitações de taxa de transferência de token ou solicitação: muitos serviços de IA impõem limites ao número de tokens ou à taxa de transferência de solicitações, principalmente ao usar modelos baseados em nuvem. O design para essas limitações requer um gerenciamento cuidadoso dos tamanhos de entrada, solicitações em lote quando necessário e, potencialmente, a implementação de mecanismos de limitação de taxa ou enfileiramento para gerenciar as expectativas do usuário e evitar interrupções no serviço.
Cenários de custo e estorno: projetar para transparência de custos envolve a implementação de recursos de rastreamento e relatórios de uso que facilitam os modelos de estorno, permitindo que as organizações aloquem custos com precisão entre os departamentos. O gerenciamento de estorno normalmente é tratado por um gateway de API, como o Gerenciamento de API do Azure.