Trabalhando no que geralmente pode ser chamado de projetos de "dados médios", consegui paralelizar meu código (principalmente para modelagem e previsão em Python) em um único sistema, em qualquer lugar de 4 a 32 núcleos. Agora, estou analisando o dimensionamento de clusters no EC2 (provavelmente com StarCluster / IPython, mas aberto a outras sugestões também), e fiquei perplexo com a maneira de reconciliar o trabalho de distribuição entre núcleos em uma instância versus instâncias em um cluster.
É prático paralelizar as instâncias e os núcleos de cada instância? Em caso afirmativo, alguém pode dar um rápido resumo dos prós + contras da execução de muitas instâncias com poucos núcleos cada versus algumas instâncias com muitos núcleos? Existe uma regra prática para escolher a proporção correta de instâncias para núcleos por instância?
Largura de banda e RAM são preocupações não triviais em meus projetos, mas é fácil identificar quando esses são os gargalos e o reajuste. Imagino que seja muito mais difícil comparar a combinação certa de núcleos com instâncias sem testes repetidos, e meus projetos variam muito para que um único teste se aplique a todas as circunstâncias. Agradecemos antecipadamente e, se não consegui pesquisar corretamente no Google, sinta-se à vontade para me indicar a resposta certa em outro lugar!
Uma regra geral é não distribuir até que você precise. Geralmente, é mais eficiente ter N servidores com uma certa capacidade que 2N servidores com metade dessa capacidade. Mais do acesso a dados será local e, portanto, rápido na memória versus lento na rede.
Em um determinado momento, a expansão de uma máquina se torna antieconômica porque o custo de recursos adicionais é escalado mais do que linearmente. No entanto, este ponto ainda é surpreendentemente alto.
Porém, na Amazon, em particular, a economia de cada tipo de instância pode variar muito se você estiver usando instâncias do mercado spot. O preço padrão mais ou menos significa que a mesma quantidade de recursos custa aproximadamente a mesma, independentemente do tipo de instância, que pode variar muito; instâncias grandes podem ser mais baratas que as pequenas, ou N instâncias pequenas podem ser muito mais baratas que uma máquina grande com recursos equivalentes.
Uma consideração massiva aqui é que o paradigma de computação pode mudar bastante quando você muda de uma máquina para várias máquinas. As compensações induzidas pela sobrecarga de comunicação podem forçá-lo a, por exemplo, adotar um paradigma paralelo a dados para escalar. Isso significa uma escolha diferente de ferramentas e algoritmo. Por exemplo, o SGD parece muito diferente na memória e no Python do que no MapReduce. Então você teria que considerar isso antes de paralelizar.
Você pode optar por distribuir o trabalho em um cluster, mesmo que um único nó e paradigmas não distribuídos funcionem para você, para garantir a confiabilidade. Se um único nó falhar, você perde toda a computação; uma computação distribuída pode potencialmente recuperar e concluir apenas a parte da computação que foi perdida.
fonte
Todas as coisas consideradas iguais (custo, desempenho da CPU, etc.), você pode escolher a menor instância que pode conter todos os meus dados na memória e expandir. Dessa maneira
Supondo que você esteja executando algum tipo de esquema de validação cruzada para otimizar algum meta-parâmetro do seu modelo, atribua um valor a cada núcleo para testar e escolha várias instâncias, conforme necessário, para cobrir todo o espaço dos parâmetros em poucas rodadas, conforme desejar.
Se seus dados não couberem na memória de um sistema, é claro que você precisará distribuir entre instâncias. Então, é uma questão de equilibrar a latência da memória (melhor com muitas instâncias) com a latência da rede (melhor com menos instâncias), mas, dada a natureza do EC2, aposto que você prefere trabalhar com poucas instâncias gordas.
fonte