Como compilar o Tensorflow com as instruções SSE4.2 e AVX?

Esta é a mensagem recebida da execução de um script para verificar se o Tensorflow está funcionando:

I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcublas.so.8.0 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcudnn.so.5 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcufft.so.8.0 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcuda.so.1 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcurand.so.8.0 locally W tensorflow/core/platform/cpu_feature_guard.cc:95] The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available on your machine and could speed up CPU computations. W tensorflow/core/platform/cpu_feature_guard.cc:95] The TensorFlow library wasn't compiled to use AVX instructions, but these are available on your machine and could speed up CPU computations. I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:910] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero 

Notei que mencionou SSE4.2 e AVX,

1) O que são SSE4.2 e AVX?

2) Como esses SSE4.2 e AVX melhoram os cálculos da CPU para as tarefas do Tensorflow.

3) Como fazer o Tensorflow compilar usando as duas bibliotecas?

Acabei de me deparar com este mesmo problema, parece que a sugestão de Yaroslav Bulatov não cobre o suporte SSE4.2, acrescentando que --copt=-msse4.2 seria suficiente. No final, eu consegui construir com sucesso

 bazel build -c opt --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-mfpmath=both --copt=-msse4.2 --config=cuda -k //tensorflow/tools/pip_package:build_pip_package 

sem receber nenhum aviso ou erro.

Provavelmente a melhor escolha para qualquer sistema é:

 bazel build -c opt --copt=-march=native --copt=-mfpmath=both --config=cuda -k //tensorflow/tools/pip_package:build_pip_package 

( Atualização: os scripts de construção podem estar comendo -march=native , possivelmente porque contém um = .)

-mfpmath=both funcionam apenas com o gcc, não com clang. -mfpmath=sse é provavelmente tão bom, se não melhor, e é o padrão para x86-64. 32-bit constrói o padrão para -mfpmath=387 , então mudar isso ajudará em 32 bits. (Mas se você quiser alto desempenho para processamento de números, você deve criar binários de 64 bits.)

Não tenho certeza do que é o padrão do TensorFlow para -O2 ou -O3 . gcc -O3 permite a otimização completa, incluindo a autovetorização, mas às vezes pode tornar o código mais lento.


O que isto faz: --copt for bazel build passa uma opção diretamente para o gcc para compilar os arquivos C e C ++ (mas não ligando, então você precisa de uma opção diferente para a otimização do tempo de link entre arquivos)

O x86-64 gcc usa como padrão apenas SSE2 ou instruções SIMD mais antigas, para que você possa executar os binários em qualquer sistema x86-64. (Veja https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html ). Não é isso que você quer. Você quer fazer um binário que aproveite todas as instruções que seu processador pode executar, porque você está apenas executando este binário no sistema onde você o construiu.

-march=native habilita todas as opções suportadas pela sua CPU, então torna -mavx512f -mavx2 -mavx -mfma -msse4.2 redundante. (Além disso, -mavx2 já habilita -mavx e -msse4.2 , então o comando de Yaroslav deveria ter sido bom). Além disso, se você estiver usando uma CPU que não suporta uma dessas opções (como o FMA), o uso de -mfma um binário que falha com instruções ilegais.

O padrão do TensorFlow ./configure é habilitar -march=native , portanto, usar isso deve evitar a necessidade de especificar manualmente as opções do compilador.

-march=native ativa -mtune=native , portanto, ele otimiza para sua CPU coisas como qual sequência de instruções AVX é melhor para cargas não alinhadas.

Isso tudo se aplica ao gcc, clang ou ICC. (Para o ICC, você pode usar -xHOST vez de -march=native .)

Vamos começar com a explicação de por que você vê esses avisos em primeiro lugar .


Muito provavelmente você não instalou o TF a partir do código-fonte e, em vez disso, usou algo como pip install tensorflow . Isso significa que você instalou binários pré-construídos (por outra pessoa) que não foram otimizados para sua arquitetura. E esses avisos informam exatamente isso: algo está disponível em sua arquitetura, mas não será usado porque o binário não foi compilado com ele. Aqui está a parte da documentação .

O TensorFlow verifica a boot, seja ela compilada com as otimizações disponíveis na CPU. Se as otimizações não estiverem incluídas, o TensorFlow emitirá avisos, por exemplo, as instruções AVX, AVX2 e FMA não incluídas.

Boa coisa é que provavelmente você só quer aprender / experimentar com o TF para que tudo funcione corretamente e você não deve se preocupar com isso


O que são SSE4.2 e AVX?

A Wikipedia tem uma boa explicação sobre SSE4.2 e AVX . Esse conhecimento não é necessário para ser bom em aprendizado de máquina. Você pode pensar neles como um conjunto de algumas instruções adicionais para um computador usar vários pontos de dados em relação a uma única instrução para executar operações que podem ser naturalmente paralelizadas (por exemplo, adicionando duas matrizes).

Ambos SSE e AVX são a implementação de uma idéia abstrata de SIMD (Single instruction, multiple data), que é

uma class de computadores paralelos na taxonomia de Flynn. Ele descreve computadores com vários elementos de processamento que executam a mesma operação em vários pontos de dados simultaneamente. Assim, tais máquinas exploram o paralelismo no nível de dados, mas não a simultaneidade: existem computações simultâneas (paralelas), mas apenas um único processo (instrução) em um dado momento.

Isso é suficiente para responder à sua próxima pergunta.


Como esses SSE4.2 e AVX melhoram os cálculos da CPU para tarefas de TF?

Eles permitem um cálculo mais eficiente de várias operações vetoriais (matriz / tensor). Você pode ler mais nesses slides


Como fazer o Tensorflow compilar usando as duas bibliotecas?

Você precisa ter um binário que foi compilado para aproveitar essas instruções. A maneira mais fácil é compilá-lo você mesmo . Como Mike e Yaroslav sugeriram, você pode usar o seguinte comando bazel

bazel build -c opt --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-mfpmath=both --copt=-msse4.2 --config=cuda -k //tensorflow/tools/pip_package:build_pip_package

Deixe-me responder sua terceira pergunta primeiro:

Se você quer rodar uma versão auto-compilada dentro de um conda-env, você pode. Estas são as instruções gerais que eu corro para obter o tensorflow para instalar no meu sistema com instruções adicionais. Nota: Esta compilation foi feita para uma compilation AMD A10-7850 (verifique sua CPU para quais instruções são suportadas … pode ser diferente) executando o Ubuntu 16.04 LTS. Eu uso o Python 3.5 dentro do meu conda-env. O crédito vai para a página de instalação da fonte tensorflow e as respostas fornecidas acima.

 git clone https://github.com/tensorflow/tensorflow # Install Bazel # https://bazel.build/versions/master/docs/install.html sudo apt-get install python3-numpy python3-dev python3-pip python3-wheel # Create your virtual env with conda. source activate YOUR_ENV pip install six numpy wheel, packaging, appdir # Follow the configure instructions at: # https://www.tensorflow.org/install/install_sources # Build your build like below. Note: Check what instructions your CPU # support. Also. If resources are limited consider adding the following # tag --local_resources 2048,.5,1.0 . This will limit how much ram many # local resources are used but will increase time to compile. bazel build -c opt --copt=-mavx --copt=-msse4.1 --copt=-msse4.2 -k //tensorflow/tools/pip_package:build_pip_package # Create the wheel like so: bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg # Inside your conda env: pip install /tmp/tensorflow_pkg/NAME_OF_WHEEL.whl # Then install the rest of your stack pip install keras jupyter etc. etc. 

Quanto à sua segunda pergunta:

Uma versão auto-compilada com otimizações vale o esforço na minha opinião. Na minha configuração particular, cálculos que costumavam levar de 560 a 600 segundos agora levam apenas cerca de 300 segundos! Embora os números exatos variem, acho que você pode esperar um aumento de velocidade de 35 a 50% em geral em sua configuração específica.

Por último sua primeira pergunta:

Muitas das respostas já foram fornecidas acima. Resumindo: AVX , SSE4.1, SSE4.2 , MFA são tipos diferentes de conjuntos de instruções estendidos em CPUs X86. Muitos contêm instruções otimizadas para processar operações matriciais ou vetoriais.

Eu destacarei meu próprio equívoco para economizar um tempo: não é que o SSE4.2 seja uma versão mais nova de instruções que substituem o SSE4.1. SSE4 = SSE4.1 (um conjunto de 47 instruções) + SSE4.2 (um conjunto de 7 instruções).

No contexto da compilation tensorflow, se o computador suportar AVX2 e AVX, e SSE4.1 e SSE4.2, você deverá colocar esses sinalizadores de otimização em todos. Não faça como eu fiz e só vá com SSE4.2 pensando que é mais novo e deve superá-lo SSE4.1. Isso é claramente errado! Eu tive que recompilar por causa disso, o que me custou uns bons 40 minutos.

Estes são conjuntos de instruções de processamento de vetores SIMD .

Usando instruções vetoriais é mais rápido para muitas tarefas; o aprendizado de máquina é uma tarefa dessas.

Citando os documentos de instalação do tensorflow :

Para ser compatível com o maior número possível de máquinas, o TensorFlow usa apenas as instruções SSE4.1 SIMD em máquinas x86. A maioria dos PCs e Macs modernos suportam instruções mais avançadas, então se você está construindo um binário que você só estará rodando em sua própria máquina, você pode habilitá-los usando --copt=-march=native em seu comando bazel build.

Graças a todas estas respostas + algumas tentativas e erros, eu consegui instalá-lo em um Mac com clang . Então, apenas compartilhando minha solução caso seja útil para alguém.

  1. Siga as instruções em Documentação – Instalando o TensorFlow a partir de fonts

  2. Quando solicitado

    Por favor especifique flags de otimização para usar durante a compilation quando a opção bazel “–config = opt” for especificada [O padrão é -march = native]

copie e cole esta string:

 -mavx -mavx2 -mfma -msse4.2 

(A opção padrão causou erros, assim como alguns dos outros sinalizadores. Eu não tenho nenhum erro com os sinalizadores acima. BTW eu respondi n para todas as outras perguntas)

Após a instalação, eu verifico uma aceleração de ~ 2x a 2,5x ao treinar modelos profundos em relação a outra instalação baseada nas rodas padrão – Instalando o TensorFlow no macOS

Espero que ajude

Eu instalei recentemente a partir da fonte e abaixo estão todas as etapas necessárias para instalá-lo a partir da fonte com as instruções mencionadas disponíveis.

Outras respostas já descrevem porque essas mensagens são mostradas. Minha resposta dá um passo-a-passo sobre como instalar, o que pode ajudar as pessoas a se esforçarem na instalação real como eu fiz.

  1. Instalar Bazel

Faça o download de uma das versões disponíveis, por exemplo, 0.5.2 . Extraia, entre no diretório e configure-o: bash ./compile.sh . Copie o executável para /usr/local/bin : sudo cp ./output/bazel /usr/local/bin

  1. Instale o Tensorflow

Clone tensorflow: git clone https://github.com/tensorflow/tensorflow.git Vá para o diretório clonado para configurá-lo: ./configure

Ele vai te fazer várias perguntas, abaixo sugeri a resposta para cada uma das perguntas, você pode, é claro, escolher suas próprias respostas como preferir:

 Using python library path: /usr/local/lib/python2.7/dist-packages Do you wish to build TensorFlow with MKL support? [y/N] y MKL support will be enabled for TensorFlow Do you wish to download MKL LIB from the web? [Y/n] Y Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native]: Do you wish to use jemalloc as the malloc implementation? [Y/n] n jemalloc disabled Do you wish to build TensorFlow with Google Cloud Platform support? [y/N] N No Google Cloud Platform support will be enabled for TensorFlow Do you wish to build TensorFlow with Hadoop File System support? [y/N] N No Hadoop File System support will be enabled for TensorFlow Do you wish to build TensorFlow with the XLA just-in-time compiler (experimental)? [y/N] N No XLA JIT support will be enabled for TensorFlow Do you wish to build TensorFlow with VERBS support? [y/N] N No VERBS support will be enabled for TensorFlow Do you wish to build TensorFlow with OpenCL support? [y/N] N No OpenCL support will be enabled for TensorFlow Do you wish to build TensorFlow with CUDA support? [y/N] N No CUDA support will be enabled for TensorFlow 
  1. O pacote pip. Para construí-lo você tem que descrever quais instruções você quer (você sabe, aqueles Tensorflow informaram que estão faltando).

Construir o script pip: bazel build -c opt --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-mfpmath=both --copt=-msse4.1 --copt=-msse4.2 -k //tensorflow/tools/pip_package:build_pip_package

Compile o pacote pip: bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg

Instale o pacote pip Tensorflow que você acabou de sudo pip install /tmp/tensorflow_pkg/tensorflow-1.2.1-cp27-cp27mu-linux_x86_64.whl : sudo pip install /tmp/tensorflow_pkg/tensorflow-1.2.1-cp27-cp27mu-linux_x86_64.whl

Agora, da próxima vez que você iniciar o Tensorflow, ele não reclamará mais sobre a falta de instruções.

Compilei um pequeno script Bash para Mac (facilmente pode ser portado para o Linux) para recuperar todos os resources da CPU e aplicar alguns deles para construir o TF. Eu estou no mestre TF e uso muitas vezes (algumas vezes em um mês).

https://gist.github.com/venik/9ba962c8b301b0e21f99884cbd35082f

Esse é o método mais simples. Apenas um passo.

Tem impacto significativo na velocidade. No meu caso, o tempo gasto para uma etapa de treinamento quase caiu pela metade.

Encaminhar construções customizadas de tensorflow

Ao criar o TensorFlow a partir do código-fonte, você executará o script de configure . Uma das perguntas que o script de configure faz é a seguinte:

 Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native] 

O script configure irá append os flag (s) que você especificar ao comando bazel que constrói o pacote pip do TensorFlow. De um modo geral, você pode responder a essa solicitação de duas maneiras:

  • Se você está construindo o TensorFlow no mesmo tipo de CPU que aquele no qual você executará o TensorFlow, então você deve aceitar o padrão ( -march=native ). Esta opção otimizará o código gerado para o tipo de CPU da sua máquina.
  • Se você está construindo o TensorFlow em um tipo de CPU, mas executará o TensorFlow em um tipo de CPU diferente, considere fornecer um sinalizador de otimização mais específico, conforme descrito na documentação do gcc .

Depois de configurar o TensorFlow como descrito na lista com marcadores precedente, você deve ser capaz de criar o TensorFlow totalmente otimizado para a CPU de destino apenas adicionando o sinalizador --config=opt a qualquer comando bazel que estiver executando.

Para ocultar esses avisos, você pode fazer isso antes do seu código real.

 import os os.environ['TF_CPP_MIN_LOG_LEVEL']='2' import tensorflow as tf 

Para compilar o TensorFlow com SSE4.2 e AVX, você pode usar

bazel build –config = mkl –config = “opt” –copt = “–march = broadwell” –copt = “- O3” // tensorflow / tools / pip_package: build_pip_package

Fonte: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/tools/docker/Dockerfile.devel-cpu-mkl