Gerenciar orçamentos, custos e cota para o Azure Machine Learning em escala organizacional
Quando você gerencia os custos de computação gerados com o Azure Machine Learning, em uma escala da organização com muitas cargas de trabalho, muitas equipes e usuários, há vários desafios de gerenciamento e otimização para resolver.
Neste artigo, apresentaremos as melhores práticas para otimizar custos, gerenciar orçamentos e compartilhar cotas com o Azure Machine Learning. Ele reflete a experiência e as lições aprendidas com a execução de equipes de machine learning internamente na Microsoft e durante a parceria com nossos clientes. Você aprenderá a:
- Otimizar recursos de computação para atender aos requisitos da carga de trabalho.
- Fazer o melhor uso do orçamento de uma equipe.
- Planejar, gerenciar e compartilhar orçamentos, custos e cotas em escala empresarial.
Otimizar a computação para atender aos requisitos da carga de trabalho
Quando você inicia um novo projeto de machine learning, pode ser necessário um trabalho exploratório para obter uma boa perspectiva dos requisitos de computação. Esta seção fornece recomendações sobre como determinar a escolha certa de SKU de VM (máquina virtual) para treinamento, para inferência ou como uma estação de trabalho.
Determinar o tamanho da computação para treinamento
Os requisitos de hardware para a carga de trabalho de treinamento podem variar de acordo com o projeto. Para atender a esses requisitos, a computação do Azure Machine Learning oferece vários tipos de VMs:
- Uso geral: proporção balanceada de CPU para memória.
- Otimizado para memória: alta proporção de memória para CPU.
- Computação otimizada: alta proporção de CPU para memória.
- Computação de alto desempenho: forneça o melhor desempenho, escalabilidade e economia da classe para várias cargas de trabalho de HPC do mundo real.
- Instâncias com GPUs: máquinas virtuais especializadas direcionadas à renderização intensa de gráficos e à edição de vídeo, bem como treinamento de modelo e inferência (ND) com aprendizado profundo.
Talvez você ainda não saiba quais são seus requisitos de computação. Nesse cenário, recomendamos começar com uma das opções padrão econômicas a seguir. Essas opções destinam-se a testes leves e a cargas de trabalho de treinamento.
Tipo | Tamanho da máquina virtual | Especificações |
---|---|---|
CPU | Standard_DS3_v2 | Quatro núcleos, 14 GB (gigabytes) de RAM, 28 GB de armazenamento |
GPU | Standard_NC6 | Seis núcleos, 56 GB (gigabytes) de RAM, 380 GB de armazenamento, GPU NVIDIA Tesla K80 |
Para você obter o melhor tamanho de VM para seu cenário, o processo pode consistir em tentativa e erro. Veja a seguir vários aspectos a serem considerados.
- Se você precisar de uma CPU:
- Use uma VM otimizada para memória se está fazendo o treinamento em conjuntos de dados grandes.
- Use uma VM com computação otimizada se está realizando uma inferência em tempo real ou outras tarefas sensíveis à latência.
- Use uma VM com mais núcleos e RAM para acelerar os tempos de treinamento.
- Se você precisar de uma GPU, consulte os tamanhos de VM otimizados para GPU para obter informações sobre como selecionar uma VM.
- Se estiver fazendo um treinamento distribuído, use tamanhos de VM que tenham várias GPUs.
- Se estiver fazendo um treinamento distribuído em vários nós, use GPUs que tenham conexões NVLink.
Enquanto você escolhe o tipo de VM e o SKU mais adequados à carga de trabalho, avalie os SKUs de VM comparáveis como uma troca entre desempenho e preço de CPU e GPU. Da perspectiva do gerenciamento de custos, um trabalho pode ser executado razoavelmente bem em vários SKUs.
Algumas GPUs, como a família NC, especialmente os SKUs NC_Promo, têm capacidades semelhantes a outras GPUs, como baixa latência e capacidade de gerenciar várias cargas de trabalho de computação em paralelo. Elas estão disponíveis com preços promocionais em comparação com algumas das outras GPUs. A seleção cuidadosa de SKUs de VM para a carga de trabalho pode gerar economias significativas no final.
Um lembrete sobre a importância da utilização é que a inscrição em um número maior de GPUs não traz necessariamente resultados mais rápidos. Em vez disso, garanta que as GPUs tenham utilização total. Por exemplo, confirme se há a necessidade da NVIDIA CUDA. Embora ela possa ser necessária para a execução de GPU de alto desempenho, seu trabalho pode não depender dela.
Determinar o tamanho da computação para inferência
Os requisitos de computação para cenários de inferência variam de acordo com os cenários de treinamento. As opções disponíveis diferem com base no fato de o cenário exigir a inferência offline em lote ou a inferência online em tempo real.
Para cenários de inferência em tempo real, considere as seguintes sugestões:
- Use as funcionalidades de criação de perfil no modelo com o Azure Machine Learning para determinar a CPU e a memória que você precisa alocar para o modelo ao implantá-lo como um serviço Web.
- Se estiver fazendo a inferência em tempo real, mas não precisar de alta disponibilidade, implante-o nas Instâncias de Contêiner do Azure (sem a seleção de SKU).
- Se estiver fazendo a inferência em tempo real, mas precisar de alta disponibilidade, implante-o no Serviço de Kubernetes do Azure.
- Se estiver usando modelos tradicionais de machine learning e receber < dez consultas/segundo, comece com um SKU de CPU. Em geral, os SKUs da série F funcionam bem.
- Se estiver usando modelos de aprendizado profundo e receber > dez consultas/segundo, experimente usar um SKU de GPU NVIDIA (em geral, o NCasT4_v3 funciona bem) com o Triton.
Para cenários de inferência em lote, considere as seguintes sugestões:
- Ao usar pipelines do Azure Machine Learning para inferência em lote, siga as diretrizes descritas em Determinar o tamanho da computação para treinamento para escolher o tamanho inicial da VM.
- Otimize o custo e o desempenho com a escala horizontal. Um dos principais métodos de otimização de custo e desempenho é paralelizar a carga de trabalho com a ajuda da etapa de execução paralela do Azure Machine Learning. Essa etapa de pipeline permite que você use muitos nós menores para executar a tarefa em paralelo, o que permite a escala horizontal. No entanto, há uma sobrecarga de paralelização. Dependendo da carga de trabalho e do grau de paralelismo que pode ser obtido, uma etapa de execução paralela pode ou não ser uma opção.
Determinar o tamanho da instância de computação
Para o desenvolvimento interativo, a instância de computação do Azure Machine Learning é recomendada. A oferta de CI (instância de computação) traz a computação de nó único vinculada a um usuário individual e pode ser usada como uma estação de trabalho na nuvem.
Algumas organizações não permitem o uso de dados de produção em estações de trabalho locais, têm restrições impostas ao ambiente de estação de trabalho ou restringem a instalação de pacotes e dependências no ambiente de TI corporativo. Uma instância de computação pode ser usada como uma estação de trabalho para superar a limitação. Ela oferece um ambiente seguro com acesso aos dados de produção e é executada em imagens fornecidas com pacotes e ferramentas populares para ciência de dados pré-instalados.
Quando a instância de computação está em execução, o usuário é cobrado pela computação de VM, pelo Standard Load Balancer (regras de saída/balanceador de carga incluído e dados processados), pelo disco do SO (disco P10 SSD Premium gerenciado), pelo disco temporário (o tipo de disco temporário depende do tamanho de VM escolhido) e pelo endereço IP público. Para reduzir os custos, recomendamos que os usuários considerem a possibilidade de:
- Iniciar e parar a instância de computação quando ela não estiver em uso.
- Trabalhar com uma amostra dos dados em uma instância de computação e expandi-lo para clusters de cálculo para trabalhar com o conjunto completo de dados
- Enviar trabalhos de experimentação no modo de destino de computação local na instância de computação durante o desenvolvimento ou o teste ou quando você alternar para a capacidade de computação compartilhada ao enviar trabalhos em escala total. Por exemplo, muitas épocas, conjunto completo de dados e pesquisa de hiperparâmetros.
Se você parar a instância de computação, ela interromperá a cobrança das horas de computação da VM, do disco temporário e dos custos dos dados processados do Standard Load Balancer. Observe que o usuário ainda paga pelo disco do SO e pelas regras de saída/balanceador de carga incluído do Standard Load Balancer, mesmo quando a instância de computação é interrompida. Todos os dados salvos no disco do SO são persistentes por meio de parada e reinicializações.
Ajustar o tamanho da VM escolhido monitorando a utilização da computação
Veja informações sobre seu uso e sua utilização da computação do Azure Machine Learning por meio do Azure Monitor. Veja detalhes sobre a implantação e o registro do modelo, os detalhes de cota como nós ativos e ociosos, os detalhes da execução como as execuções canceladas e concluídas, bem como a utilização de computação para GPU e CPU.
Com base nos insights dos detalhes de monitoramento, você pode planejar ou ajustar melhor o uso de recursos entre toda a equipe. Por exemplo, se você observar muitos nós ociosos na última semana, poderá trabalhar com os proprietários do workspace correspondente para atualizar a configuração do cluster de cálculo a fim de evitar esse custo extra. Os benefícios da análise dos padrões de utilização podem ajudar na previsão de custos e nos aprimoramentos de orçamento.
Acesse essas métricas diretamente no portal do Azure. Acesse o workspace do Azure Machine Learning e selecione Métricas na seção de monitoramento no painel esquerdo. Em seguida, você pode selecionar detalhes sobre o que deseja ver, como métricas, agregação e período. Para obter mais informações, confira a página de documentação Monitorar o Azure Machine Learning.
Alternar entre a computação em nuvem local, de nó único e de vários nós durante o desenvolvimento
Há diferentes requisitos de computação e ferramentas em todo o ciclo de vida do machine learning. O Azure Machine Learning pode ser acessado por meio de uma interface da CLI ou do SDK em praticamente qualquer configuração de estação de trabalho preferencial para atender a esses requisitos.
Para reduzir os custos e trabalhar de maneira produtiva, recomendamos:
- Clonar a base de código de experimentação localmente usando o Git e enviar trabalhos para a computação em nuvem usando o SDK ou a CLI do Azure Machine Learning.
- Se o conjunto de dados for grande, considere a possibilidade de gerenciar uma amostra dos dados na estação de trabalho local, mantendo o conjunto de dados completo no armazenamento em nuvem.
- Parametrizar a base de código de experimentação a fim de configurar os trabalhos para execução com um número variável de épocas ou em conjuntos de dados de tamanhos diferentes.
- Não embuta em código o caminho da pasta do conjunto de dados. Em seguida, você poderá reutilizar com facilidade a mesma base de código com conjuntos de dados diferentes e no contexto de execução local e na nuvem.
- Inicializar seus trabalhos de experimentação no modo de destino de computação local durante o desenvolvimento ou teste ou ao alternar para uma capacidade de cluster de cálculo compartilhada ao enviar trabalhos em escala total.
- Se o conjunto de dados for grande, trabalhe com uma amostra dos dados na estação de trabalho local ou da instância de computação, escalando-o para a computação em nuvem no Azure Machine Learning a fim de trabalhar com o conjunto completo de dados.
- Quando os trabalhos levarem muito tempo para serem executados, considere a possibilidade de otimizar a base de código para treinamento distribuído visando permitir a expansão horizontal.
- Projetar as cargas de trabalho de treinamento distribuído visando a elasticidade de nó, a fim de permitir o uso flexível da computação de nó único e de vários nós e facilitar o uso da computação que possa ter preempção.
Combinar tipos de computação usando pipelines do Azure Machine Learning
Ao orquestrar seus fluxos de trabalho de machine learning, você pode definir um pipeline com várias etapas. Cada etapa do pipeline pode ser executada em um tipo próprio de computação. Isso permite otimizar o desempenho e o custo para atender a diferentes requisitos de computação em todo o ciclo de vida do machine learning.
Fazer o melhor uso do orçamento de uma equipe
Embora as decisões de alocação de orçamento possam estar fora do alcance do controle de uma equipe individual, normalmente, uma equipe é capacitada a usar o respectivo orçamento alocado para as melhores necessidades. Ao trocar a prioridade do trabalho pelo desempenho e pelo custo com bom senso, uma equipe pode obter maior utilização do cluster, reduzir o custo geral e usar um número maior de horas de computação com o mesmo orçamento. Isso pode resultar em uma produtividade aprimorada da equipe.
Otimizar os custos de recursos de computação compartilhados
O segredo para otimizar os custos de recursos de computação compartilhados é garantir que eles estejam sendo usados na capacidade total. Veja algumas dicas para otimizar os custos de recursos compartilhados:
- Quando você usar instâncias de computação, ligue-as somente quando tiver um código para executar. Desligue-as quando elas não estiverem sendo usadas.
- Quando você usar clusters de cálculo, defina a contagem mínima de nós como zero e a contagem máxima de nós como um número que seja avaliado de acordo com suas restrições de orçamento. Use a Calculadora de Preços do Azure para calcular o custo de utilização total de um nó de VM do SKU de VM escolhido. O dimensionamento automático reduzirá verticalmente todos os nós de computação quando ninguém os estiver usando. Ele só escalará verticalmente para o número de nós dentro do seu orçamento. Configure o dimensionamento automático para reduzir verticalmente todos os nós de computação.
- Monitore as utilizações de recursos, como utilização da CPU e da GPU ao treinar modelos. Se os recursos não estão sendo totalmente usados, modifique o código para usar melhor os recursos ou reduza verticalmente para tamanhos de VM menores ou mais baratos.
- Avalie se você pode criar recursos de computação compartilhados para sua equipe a fim de evitar perdas de eficiência de computação causadas por operações de escala do cluster.
- Otimize as políticas de tempo limite de dimensionamento automático do cluster de cálculo com base nas métricas de uso.
- Use cotas de workspace para controlar a quantidade de recursos de computação aos quais os workspaces individuais têm acesso.
Introduzir a prioridade de agendamento criando clusters para vários SKUs de VM
Operando sob restrições de cota e orçamento, uma equipe precisa trocar a execução em tempo hábil de trabalhos pelo custo, a fim de garantir que trabalhos importantes sejam executados em tempo hábil e um orçamento seja usado da melhor maneira possível.
Para dar suporte a uma melhor utilização da computação, as equipes são incentivadas a criar clusters de vários tamanhos e com prioridades de VM dedicadas e de baixa prioridade. Os tipos de computação de baixa prioridade usam a capacidade excedente no Azure e, portanto, apresentam taxas com desconto. Por outro lado, esses computadores podem ter preempções sempre que uma solicitação de prioridade mais alta é recebida.
Usando os clusters de tamanho e prioridade variáveis, uma noção de prioridade de agendamento pode ser apresentada. Por exemplo, quando trabalhos experimentais e de produção competem pela mesma cota de GPU NC, um trabalho de produção pode ter preferência de execução em relação ao trabalho experimental. Nesse caso, execute o trabalho de produção no cluster de cálculo dedicado e o trabalho experimental no cluster de cálculo de baixa prioridade. Quando a cota ficar curta, o trabalho experimental terá uma preempção em favor do trabalho de produção.
Além da prioridade da VM, considere a execução de trabalhos em vários SKUs de VM. Pode acontecer de um trabalho levar mais tempo para ser executado em uma instância de VM com uma GPU P40 do que em uma GPU V100. No entanto, como as instâncias de VM V100 podem estar ocupadas ou a cota pode estar totalmente usada, o tempo até a conclusão na P40 ainda pode ser mais rápido do ponto de vista da taxa de transferência do trabalho. Você também pode considerar a execução de trabalhos com prioridade mais baixa em instâncias de VM menos eficientes e mais baratas da perspectiva do gerenciamento de custos.
Encerrar uma execução antecipadamente quando o treinamento não for convergente
Ao fazer experimentos continuamente para aprimorar um modelo em relação à linha de base, você pode fazer várias execuções de experimento, cada uma com configurações ligeiramente diferentes. Para uma execução, você pode ajustar os conjuntos de dados de entrada. Para outra, você pode fazer uma alteração de hiperparâmetro. Nem todas as alterações podem ser tão eficazes quanto as outras. Você detecta precocemente que uma alteração não teve o efeito pretendido na qualidade do treinamento do modelo. Para detectar se o treinamento não será convergente, monitore o progresso do treinamento durante uma operação. Por exemplo, registrando métricas de desempenho em log após cada época de treinamento. Considere o encerramento antecipado do trabalho para liberar recursos e orçamento para outra avaliação.
Planejar, gerenciar e compartilhar orçamentos, custos e cotas
À medida que uma organização aumenta o número de casos de uso e as equipes de machine learning, ela exige um aumento da maturidade operacional da TI e das finanças, bem como a coordenação entre equipes individuais de machine learning para garantir operações eficientes. A capacidade de escala da empresa e o gerenciamento de cotas tornam-se importantes para lidar com a escassez de recursos de computação e superar a sobrecarga de gerenciamento.
Esta seção discute as melhores práticas de planejamento, gerenciamento e compartilhamento de orçamentos, custos e cotas em escala empresarial. Ela se baseia em aprendizados do gerenciamento de muitos recursos de treinamento de GPU para machine learning internamente na Microsoft.
Noções básicas sobre gastos com recursos com o Azure Machine Learning
Um dos maiores desafios como administrador para planejar as necessidades de computação é começar do zero sem informações históricas como uma estimativa de linha de base. Na prática, a maioria dos projetos começará com um orçamento pequeno como uma primeira etapa.
Para entender para onde o orçamento está indo, é essencial saber a proveniência dos custos do Azure Machine Learning:
- O Azure Machine Learning só cobra a infraestrutura de computação usada e não adiciona uma sobrecarga aos custos de computação.
- Quando um workspace do Azure Machine Learning é criado, também são criados alguns outros recursos para habilitar o Azure Machine Learning: Key Vault, Application Insights, Armazenamento do Azure e Registro de Contêiner do Azure. Esses recursos são usados no Azure Machine Learning, e você pagará por eles.
- Há custos associados à computação gerenciada, como clusters de treinamento, instâncias de computação e pontos de extremidade de inferência gerenciados. Com esses recursos de computação gerenciados, há os seguintes custos de infraestrutura a serem considerados: máquinas virtuais, rede virtual, balanceador de carga, largura de banda e armazenamento.
Acompanhe os padrões de gastos e obtenha melhores relatórios com a marcação
Os administradores geralmente desejam controlar os custos em diferentes recursos no Aprendizado de Máquina do Azure. A marcação é uma solução natural para esse problema e se alinha com a abordagem geral usada pelo Azure e muitos outros provedores de serviços de nuvem. Com o suporte a tags, agora você pode ver a divisão de custos no nível de computação, concedendo acesso a uma exibição mais granular para ajudar com melhor monitoramento de custos, relatórios aprimorados e maior transparência.
A marcação permite que você coloque marcas personalizadas em seus espaços de trabalho e cálculos (de modelos do Gerenciador de Recursos do Azure e do estúdio de Aprendizado de Máquina do Azure) para filtrar ainda mais esses recursos no Gerenciamento de Custos da Microsoft com base nessas marcas para observar padrões de gastos. Essa funcionalidade pode ser melhor utilizada para cenários internos de chargeback. Além disso, as tags podem ser úteis para capturar metadados ou detalhes associados à computação, como um projeto, uma equipe ou um determinado código de cobrança. Isso torna a marcação muito benéfica para medir quanto dinheiro você está gastando em diferentes recursos e, portanto, obter insights mais profundos sobre seus padrões de custo e gastos entre equipes ou projetos.
Há também tags injetadas no sistema colocadas em cálculos que permitem filtrar na página Análise de custos pela tag "Tipo de computação" para ver um detalhamento computacional do seu gasto total e determinar qual categoria de recursos de computação pode estar atribuindo à maioria dos seus custos. Isso é particularmente útil para obter mais visibilidade sobre seu treinamento versus inferência de padrões de custo.
Controlar e restringir o uso de computação por política
Quando você gerencia um ambiente do Azure com muitas cargas de trabalho, pode ser complicado manter a visão geral sobre os gastos com recursos. O Azure Policy pode ajudar a controlar os gastos com recursos restringindo padrões de uso específicos em todo o ambiente do Azure.
Particularmente para o Azure Machine Learning, recomendamos configurar políticas para permitir apenas o uso de SKUs de VM específicas. As políticas podem ajudar a impedir e controlar a seleção de VMs caras. Também podem ser usadas para impor o uso de SKUs de VM de baixa prioridade.
Alocar e gerenciar cotas com base na prioridade dos negócios
O Azure permite definir limites para alocação de cota em uma assinatura e em um workspace do Azure Machine Learning. Restringir quem pode gerenciar a cota por meio do RBAC (controle de acesso baseado em função) do Azure pode ajudar a garantir a utilização de recursos e a previsibilidade dos custos.
A disponibilidade da cota de GPU pode ser rara nas assinaturas. Para garantir a alta utilização de cota entre cargas de trabalho, recomendamos monitorar se a cota está sendo bem usada e atribuída entre as cargas de trabalho.
Na Microsoft, é determinado periodicamente se as cotas de GPU estão sendo bem usadas e alocadas entre as equipes de machine learning pela avaliação das necessidades de capacidade em relação à prioridade dos negócios.
Confirmar a capacidade com antecedência
Se você tiver uma boa estimativa de quanta computação será usada no próximo ano ou nos próximos anos, poderá comprar Instâncias de VM Reservadas do Azure com desconto. Há termos de compra de um ou três anos. Como as Instâncias de VM Reservadas do Azure têm desconto, pode haver uma economia significativa em comparação com os preços de pagamento conforme o uso.
O Azure Machine Learning dá suporte a instâncias de computação reservadas. Os descontos são aplicados automaticamente à computação gerenciada do Azure Machine Learning.
Gerenciar a retenção de dados
Sempre que um pipeline de machine learning é executado, conjuntos de dados intermediários podem ser gerados em cada etapa do pipeline para cache e reutilização de dados. O crescimento dos dados como resultado desses pipelines de machine learning pode se tornar um ponto problemático para uma organização que executa muitos experimentos de machine learning.
Normalmente, os cientistas de dados não gastam tempo para limpar os conjuntos de dados intermediários gerados. Ao longo do tempo, o volume de dados gerados se acumulará. O Armazenamento do Azure é fornecido com uma funcionalidade para aprimorar o gerenciamento do ciclo de vida dos dados. Usando o gerenciamento do ciclo de vida do Armazenamento de Blobs do Azure, você pode configurar políticas gerais para mover dados que não são usados para camadas de armazenamento mais frio e reduzir os custos.
Considerações sobre a otimização de custo de infraestrutura
Rede
O custo de rede do Azure é gerado da largura de banda de saída do datacenter do Azure. Todos os dados de entrada em um datacenter do Azure são gratuitos. O segredo para reduzir o custo de rede é implantar todos os recursos na mesma região de datacenter, sempre que possível. Se você puder implantar o workspace e a computação do Azure Machine Learning na mesma região dos dados, poderá aproveitar um custo reduzido e um desempenho mais alto.
O ideal é ter uma conexão privada entre a sua rede local e a rede do Azure para ter um ambiente de nuvem híbrida. O ExpressRoute permite que você faça isso, mas considerando o alto custo dele, pode ser mais econômico sair de uma configuração de nuvem híbrida e migrar todos os recursos para a nuvem do Azure.
Registro de Contêiner do Azure
Para o Registro de Contêiner do Azure, os fatores determinantes para a otimização de custo incluem:
- Taxa de transferência necessária para downloads de imagem do Docker do registro de contêiner para o Azure Machine Learning
- Requisitos para recursos de segurança corporativa, como o Link Privado do Azure
Em cenários de produção nos quais a alta taxa de transferência ou a segurança corporativa é necessária, o SKU Premium do Registro de Contêiner do Azure é recomendado.
Em cenários de desenvolvimento/teste nos quais a taxa de transferência e a segurança são menos críticas, recomendamos o SKU Standard ou o SKU Premium.
O SKU Básico do Registro de Contêiner do Azure não é recomendado para o Azure Machine Learning. Ele não é recomendado devido à baixa taxa de transferência e ao baixo armazenamento incluído, que pode ser rapidamente excedido por imagens relativamente grandes (mais de 1 GB) do Docker no Azure Machine Learning.
Considere a disponibilidade do tipo de computação ao escolher regiões do Azure
Ao escolher uma região para sua computação, mantenha a disponibilidade da cota de computação em mente. As regiões populares e maiores, como Leste dos EUA, Oeste dos EUA, e Oeste da Europa, tendem a ter valores de cota padrão mais altos e maior disponibilidade da maioria das CPUs e das GPUs, em comparação com algumas outras regiões com restrições de capacidade mais rígidas em vigor.
Saiba mais
Próximas etapas
Para saber mais sobre como organizar e configurar ambientes do Azure Machine Learning, confira Organizar e configurar ambientes do Azure Machine Learning.
Para saber mais sobre as melhores práticas de DevOps de machine learning com o Azure Machine Learning, confira Guia de DevOps de machine learning.