Aceleração de visão computacional com SIMD no ESP32-S3 de 2 dólares
(shraiwi.github.io)- O conjunto de instruções SIMD de 128 bits do ESP32-S3 de baixo custo foi usado para acelerar o detector de características FAST, processando frames QVGA (320×240) em cerca de 6 ms
- O chip é um microcontrolador com CPU dual-core de até 240 MHz, WiFi e Bluetooth Low Energy, e seu manual de referência técnica inclui suporte SIMD limitado
- O ponto central da implementação é processar 16 pixels de 8 bits de uma vez no pré-teste de cantos do FAST, contornando limitações de leitura desalinhada e de comparação signed
- Para adaptar pixels unsigned de 8 bits a comparações signed, foi usada a propriedade
x - 128 == x ^ 0x80para converter os valores com XOR 0x80 - A vazão de teste aumentou de 5,1 MP/s para 11,2 MP/s, chegando a um nível em que o ESP32-S3 consegue processar também streams VGA a 30 fps
Acelerando o detector de características FAST no ESP32-S3
- Foi implementado um detector de características FAST acelerado por SIMD para o ESP32-S3, com desempenho de aproximadamente 2x em relação à implementação de referência
- Leva cerca de 6 ms para processar um frame QVGA (320×240)
- O ESP32-S3 é um microcontrolador barato, mas inclui CPU dual-core de até 240 MHz, WiFi e Bluetooth Low Energy
- O manual de referência técnica do ESP32-S3 confirma a presença de suporte limitado a instruções SIMD
Instruções SIMD pouco conhecidas e preparação da implementação
- As instruções SIMD do ESP32-S3 não eram um recurso secreto, mas eram relativamente pouco conhecidas
- Há três referências úteis
- Blog de Larry Bank: exploração dos recursos e um exemplo mínimo
esp-dsp: biblioteca da Espressif usada para funções com perfil de DSP, como convolution e FFTesp-dl: biblioteca da Espressif usada para aceleração de IA on-chip
- Durante a implementação, também foi aprendido o básico da estrutura de assembly do ESP32-S3, e foi criado um alocador básico de registradores próprio, chamado
basm
Como o pré-teste de cantos do FAST é processado com SIMD
- O pré-teste de cantos do detector de características FAST amostra pixels nas direções norte, sul, leste e oeste para verificar se há pelo menos 3 pixels “extremos”
- Aqui, pixels extremos são aqueles cuja diferença absoluta em relação ao pixel central ultrapassa um determinado limiar
- Como cada registrador vetorial pode armazenar 16 valores de 8 bits, a implementação foi organizada para calcular de uma vez a contagem de extrema de 16 pixels
- Quatro blocos de pixels são amostrados em cada uma das direções leste, oeste, norte e sul, e comparados com os pixels centrais correspondentes
Restrições do SIMD do ESP32-S3 e como foram contornadas
- A primeira limitação é que a ISA não permite leitura desalinhada direta
- Assumindo que o pixel central está alinhado, os blocos leste e oeste ficam desalinhados
- Os blocos leste e oeste são obtidos com uma instrução que concatena dois registradores adjacentes e extrai uma fatia parcial
- A segunda limitação é que o ESP32-S3 implementa apenas comparações signed de 8 bits
- Os dados de pixel são armazenados como unsigned de 8 bits, então interpretá-los diretamente como signed faz com que o intervalo
[128, 255]seja mapeado de forma não linear para[-128, -1] - Nessa condição, as operações de comparação não funcionam corretamente
- Os dados de pixel são armazenados como unsigned de 8 bits, então interpretá-los diretamente como signed faz com que o intervalo
Adaptando pixels unsigned a comparações signed
- Os valores dos pixels precisam ser deslocados de
[0, 255]para[-128, 127]para que comparações e aritmética funcionem de forma significativa - À primeira vista, pareceria suficiente subtrair 128, mas isso causa problemas porque as operações aritméticas SIMD do ESP32-S3 usam todas aritmética saturada
- Valores de pixel acima de 127 não sofrem underflow corretamente e acabam limitados em
-128
- Valores de pixel acima de 127 não sofrem underflow corretamente e acabam limitados em
- A solução foi usar uma forma de subtrair 128 em paralelo sem uma instrução de subtração
- Em signed de 8 bits, o bit mais significativo tem peso posicional
-128 x - 128equivale a inverter o bit mais significativo- Por isso, foi usada a relação
x - 128 == x ^ 0x80
- Em signed de 8 bits, o bit mais significativo tem peso posicional
- Sempre que um valor unsigned de 8 bits é carregado, ele é convertido com XOR em
0x80para uma faixa linear na qual aritmética e comparações funcionam
Resultados de desempenho e possibilidade de processamento em tempo real
- Com essas duas técnicas de contorno, foi implementado um pré-teste de cantos do FAST acelerado por SIMD
- Também foi escrita uma função de pontuação acelerada por SIMD com uma combinação de operações semelhante, mas os detalhes não são abordados
- Nos testes, a vazão do detector de características FAST aumentou de 5,1 MP/s para 11,2 MP/s
- A vazão passou para cerca de 220% do nível anterior
- Esse desempenho fica dentro de uma faixa aceitável para tarefas de visão computacional em tempo real, permitindo que o ESP32-S3 processe com folga um stream VGA a 30 fps
1 comentários
Comentários do Hacker News
porque grandes empresas exploram fazendas locais e mantêm, na prática, monopólios regionais, forçando essas fazendas a vender para elas por preços muito abaixo do valor real
países do mundo inteiro estão comprando essas coisas na casa dos bilhões de unidades para vigiar cidadãos, e o Big Brother acaba criando uma economia de escala gigantesca
parece uma espécie de Zynq barato para visão computacional
https://wiki.sipeed.com/hardware/en/tang/Tang-Nano-4K/Nano-4...
https://www.aliexpress.us/item/3256806880637138.html
a variante S3 justifica facilmente o pequeno custo extra, porque tem SIMD e FPU, ficando facilmente mais de uma ordem de grandeza mais rápida
https://github.com/espressif/esp-dl/tree/master/examples/fac...
detecção de pessoas em 54 ms é impressionante: https://github.com/espressif/esp-tflite-micro?tab=readme-ov-...
trabalhamos diretamente com vários fornecedores para fazer otimizações de baixo nível para tarefas de deep learning, visão computacional e processamento digital de sinais em dezenas de arquiteturas de microcontroladores e CPUs, aceleradores especializados (incluindo computação neuromórfica) e GPUs de edge
o ESP32 está incluído: https://docs.edgeimpulse.com/docs/edge-ai-hardware/mcu/espre...
é bem impressionante poder enviar modelos TensorFlow, PyTorch e JAX e receber imediatamente uma biblioteca C++ otimizada com algumas linhas de Python no notebook
também há um Studio para treinar modelos, além de otimização de hiperparâmetros com consciência de hardware para encontrar o melhor modelo de acordo com arquiteturas projetadas para rodar bem em vários hardwares embarcados e com a latência e o uso de memória do dispositivo de destino
Features from accelerated segment test: https://en.wikipedia.org/wiki/Features_from_accelerated_segm...
também queria saber se chips nessa faixa de preço têm algo parecido com TPU
Neon é uma extensão opcional de instruções SIMD do ARMv7 e ARMv8, então do Pi Zero para cima há extensão SIMD
entendo que o Orrin Nano entrega 40 TOPS, o que já seria suficiente para nível Copilot+. "A PCIe Coral TPU Finally Works on Raspberry Pi 5" https://news.ycombinator.com/item?id=38310063
segundo https://phys.org/news/2024-06-infrared-visible-device-2d-mat..., um comprimento de onda infravermelho de 1550 nm foi convertido para luz visível de 622 nm, e a onda de luz de saída pode ser detectada por câmeras convencionais baseadas em silício
esse processo preserva a coerência, então, se um padrão específico for gravado na frequência infravermelha de entrada, ele seria automaticamente transmitido para a nova frequência de saída
"Show HN: PicoVGA Library – VGA/TV Display on Raspberry Pi Pico" https://news.ycombinator.com/item?id=35117847#35120403
https://news.ycombinator.com/item?id=40275530
"Designing a SIMD Algorithm from Scratch" https://news.ycombinator.com/item?id=38450374
As instruções SIMD do ESP32-S3 parecem ter sido projetadas para acelerar a inferência de modelos de IA quantizados (https://github.com/espressif/esp-dl), além de incluir processamento de sinais como FFT
No sentido de que existem instruções específicas para ajudar na inferência de ML, talvez desse para chamá-lo de algo parecido com uma TPU. Por exemplo,
EE.VRELU.Sxexecuta a operação ReLUAinda assim, usar essas instruções continua consumindo tempo de CPU, e normalmente uma TPU opera de forma assíncrona em um núcleo de processamento separado, então isso está mais para ARM NEON
O software e a documentação eram bem bons, mas infelizmente ele não se popularizou
Hoje em dia é fácil encontrar placas de desenvolvimento baratas baseadas em RV1103 ("LuckFox"), BL808 ("Ox64/Pine64") e CV1800B/SG20002 ("MilkV"), e todas têm algum recurso básico parecido com TPU
Porém, como foram projetadas como placas Linux, tudo relacionado à TPU é extremamente abstraído e quase não há documentação interna, então não fica nada claro se é uma TPU de verdade ou uma imitação feita com otimizações espertas de código
À primeira vista, o MicroPython parece bastante acessível, e fico curioso se seria fácil portar esse código para WebAssembly
É possível experimentar casos de uso de dispositivos em https://micropython.org/unicorn/
Também pode ser usado no PyScript para desenvolvimento no lado do cliente, e há uma ponte com JavaScript/DOM
https://pyscript.net/tech-preview/micropython/about.html
Pela minha experiência, usar Rust no modo no-std no ESP32 também não é ruim, mas a parte de integração com componentes como Wi‑Fi, rede ou câmera ainda é menos refinada
Como outros comentários mencionam, o suporte a SIMD e assembly em Rust é suficiente
Antes de mergulhar de vez, seria bom perguntar nos chats de Rust embarcado ou Rust para ESP32
Colocar bastante SIMD junto com SMT-4 ou SMT-8 pode permitir que as threads escondam a latência e talvez ofereça melhor desempenho por área