1 pontos por GN⁺ 2023-12-25 | 1 comentários | Compartilhar no WhatsApp
  • StreamDiffusion é um pipeline que aprimora a geração de imagens baseada em difusão para geração interativa em tempo real, com o objetivo de melhorar o desempenho das técnicas existentes de geração de imagens por difusão
  • Os recursos principais incluem Stream Batch, Residual Classifier-Free Guidance, Stochastic Similarity Filter, IO Queues, pré-computação de KV-cache e ferramentas de aceleração de modelo
  • Em um ambiente com RTX 4090, Core i9-13900K e Ubuntu 22.04.3 LTS, o SD-turbo registrou Txt2Img 106.16fps e Img2Img 93.897fps com 1 denoising step
  • As demos em tempo real estão em demo/realtime-txt2img e demo/realtime-img2img, e a demo de Img2Img usa feed ao vivo da webcam ou captura de tela no navegador
  • É usado envolvendo o StableDiffusionPipeline do Diffusers, e é possível configurar execução mais rápida com merge de LCM-LoRA, Tiny VAE, xformers e aceleração com TensorRT

Objetivo e desempenho do StreamDiffusion

  • StreamDiffusion é um pipeline de difusão para geração interativa em tempo real
  • Seu objetivo é oferecer melhorias de desempenho para as técnicas atuais de geração de imagens baseadas em difusão
  • O artigo está ligado a arXiv 2312.12491 e Hugging Face Papers
  • O ambiente de medição de desempenho para geração de imagens com o pipeline proposto foi o seguinte
    • GPU: RTX 4090
    • CPU: Core i9-13900K
    • OS: Ubuntu 22.04.3 LTS
  • Tabela de desempenho
    • SD-turbo: denoising step 1, Txt2Img 106.16fps, Img2Img 93.897fps
    • LCM-LoRA + KohakuV2: denoising step 4, Txt2Img 38.023fps, Img2Img 37.133fps

Recursos principais

  • Stream Batch

    • Simplifica o processamento de dados por meio de operações de batch eficientes
  • Residual Classifier-Free Guidance

    • Um mecanismo de guidance aprimorado que reduz cálculos redundantes
  • Stochastic Similarity Filter

    • Uma técnica avançada de filtragem que melhora a eficiência de uso da GPU
  • IO Queues

    • Um recurso que gerencia com eficiência as operações de entrada e saída para ajudar em uma execução mais fluida
  • Pre-Computation for KV-Caches

    • Aumenta a velocidade de processamento ao otimizar a estratégia de cache
  • Model Acceleration Tools

    • Usa várias ferramentas para otimização do modelo e melhoria de desempenho

Instalação e forma de execução

  • O StreamDiffusion pode ser instalado com pip, conda ou Docker
  • Exemplos de ambiente Python recomendados são um ambiente conda baseado em python=3.10 ou venv
  • Os exemplos de instalação do PyTorch diferenciam CUDA 11.8 e CUDA 12.1
    • CUDA 11.8: torch==2.1.0, torchvision==0.16.0, xformers
    • CUDA 12.1: torch==2.1.0, torchvision==0.16.0, xformers
  • Formas de instalação para o usuário
  • No Windows, ao instalar a versão estável, pode ser necessário instalar pywin32 adicionalmente
  • A instalação via Docker é voltada para ambientes preparados para TensorRT, e a execução é feita com a opção --gpus all após docker build

Demos e exemplos de uso

  • Os exemplos podem ser executados no diretório examples
  • A demo de Txt2Img em tempo real está no diretório demo/realtime-txt2img
  • A demo de Img2Img em tempo real está no diretório demo/realtime-img2img
    • É possível usar feed ao vivo da webcam ou captura de tela no navegador
  • O fluxo básico de uso consiste em carregar o StableDiffusionPipeline do Diffusers e então envolvê-lo com StreamDiffusion
  • O exemplo de Img2Img carrega o modelo KBlueLeaf/kohaku-v2.1 e configura o stream com t_index_list=[32, 45]
    • Se o modelo não for LCM, usa load_lcm_lora() e fuse_lora()
    • Para aceleração adicional, usa o Tiny VAE de madebyollin/taesd
    • Ativa a atenção com eficiência de memória do xformers com enable_xformers_memory_efficient_attention()
  • O exemplo de Txt2Img usa t_index_list=[0, 16, 32, 45] e recomenda cfg_type="none" para texto-para-imagem
  • O número de warmups deve ser pelo menos len(t_index_list) x frame_buffer_size

Aceleração com TensorRT

  • Para geração mais rápida, o código de ativação do xformers pode ser substituído pelo código de aceleração com TensorRT
  • Usa accelerate_with_tensorrt de streamdiffusion.acceleration.tensorrt
  • A configuração de exemplo passa stream, "engines", max_batch_size=2
  • A extensão do TensorRT é necessária, e a construção dos engines leva tempo
  • Após a construção dos engines, a execução fica mais rápida do que nos exemplos anteriores

Stochastic Similarity Filter

  • O Stochastic Similarity Filter reduz o trabalho de transformação em entradas de vídeo quando há pouca mudança em relação ao frame anterior
  • Ao reduzir o trabalho de transformação, alivia a carga de processamento da GPU
  • O modo de uso é chamar stream.enable_similar_image_filter()
  • Argumentos configuráveis
    • similar_image_filter_threshold: limite de similaridade entre o frame anterior e o frame atual antes de pausar o processamento
    • similar_image_filter_max_skip_frame: intervalo máximo permitido durante a pausa antes de retomar a transformação

Residual CFG

  • RCFG é um método que implementa uma aproximação de CFG com complexidade computacional competitiva em relação ao caso sem uso de CFG
  • Pode ser definido pelo argumento cfg_type de StreamDiffusion
  • Existem dois tipos de RCFG
    • RCFG Self-Negative: método sem item de definição de negative prompt
    • RCFG Onetime-Negative: método em que é possível definir negative prompt
  • Comparação de complexidade computacional
    • Sem CFG: N
    • CFG normal: 2N
    • RCFG Self-Negative: N
    • RCFG Onetime-Negative: N+1
  • Os valores de cfg_type são os seguintes
    • Sem CFG: "none"
    • CFG normal: "full"
    • RCFG Self-Negative: "self"
    • RCFG Onetime-Negative: "initialize"
  • delta tem um efeito de atenuação que ajusta o efeito do RCFG

Modelos e recursos usados

1 comentários

 
GN⁺ 2023-12-25
Opiniões no Hacker News
  • O artigo no Arxiv está aqui: https://arxiv.org/abs/2312.12491
    Acho que dá para deixar mais rápido do que as medições básicas em uma 4090. Com SDXL Turbo, cheguei a 10 fps mesmo sem otimização, com 1 iteração
    Ainda assim, melhorias como o filtro de similaridade estocástico, que evita gerações desnecessárias, parecem boas para obter resultados rápidos sem manter a GPU travada em 100% o tempo todo

  • É quase irreal. Parece que 10 anos se passaram em 1 ano

    • Estou esperando o momento em que isso possa fazer meu trabalho por mim, para eu rodar no PC e conectar ao Slack. Aí meu empregador receberia resultados parecidos com os que eu entregaria manualmente, eu receberia salário sem precisar gastar tempo realmente trabalhando e finalmente poderia me concentrar nos meus hobbies. No fim, é para lá que tudo está indo, certo?
    • Todo o ecossistema de IA open source agora está com essa sensação. Quase todos os dias aparece um novo avanço que torna possível algo antes considerado impossível, e é muito difícil acompanhar as mudanças
    • Como desenvolvedor frontend, agora entendo quem reclamava que o mundo de frontend mudava rápido demais para acompanhar
    • Esses softwares evoluem mais rápido do que eu consigo dar apt-get install
    • Isso me lembra jogos incrementais (https://www.reddit.com/r/incremental_games/). Mas é melhor não começar esses jogos. Eles podem arruinar um feriado
  • Acabei de testar a demo realtime-text2img, e usar npm no frontend parece exagero para esse caso. Alterei para gerar apenas 1 imagem em vez de 16, e funciona bem até em um notebook com RTX-3080. Parece gerar talvez umas 2 imagens por segundo
    Edit: a demo examples\screen dá uma sensação quase em tempo real. A janela mostra 4 fps, mas não sei exatamente o que isso significa
    Edit: porém, a força de remoção de ruído do img2img é muito baixa, então a imagem retornada difere só um pouquinho da original

    • Fico curioso sobre a qualidade real, a variedade e a aderência ao prompt. Estou sem acesso à GPU por alguns dias, então não consigo verificar por conta própria
      Artigos sobre modelos generativos são sempre difíceis de avaliar antes de rodá-los pessoalmente. Como precisam mostrar resultados aos revisores, acabam incluindo resultados selecionados. Não acho isso bom, mas vejo que essa é a realidade atual
      Aqui eles usam um autoencoder pequeno? O Artspew também fazia isso e alcançava FPS mais alto, mas não usava TensorRT, usava Triton, e a qualidade era péssima. Ainda assim, era legal
      De qualquer forma, mesmo que a qualidade fique bem abaixo do que foi mostrado, ainda é impressionante, mas na prática é difícil saber
  • Fico me perguntando se 100 fps significa que dá para inserir uma nova entrada a cada 10 ms e receber uma nova saída a cada 10 ms. Ou é preciso agrupar as entradas em lotes para obter essa vazão média?

    • Não testei pessoalmente, mas meu palpite é que processamento em lote não seja necessário
      A parte lenta do modelo é a etapa de carregar o modelo. Depois que ele está carregado, você pode enviar a entrada que quiser
      Minha intuição é que o processo de analisar e enviar os dados de imagem não seria o gargalo aqui
  • Funcionou quase exatamente como estava na documentação. A maioria dessas demos costuma quebrar e gerar erros estranhos e profundos, mas essa foi tranquila
    Bem feita. Vale testar. Se você quiser criar algo que não seja em estilo anime, dá para trocar o modelo no server.py de realtime-txt2img. Por exemplo, especificar https://huggingface.co/runwayml/stable-diffusion-v1-5 também funciona bem
    O resultado é realmente rápido. Não é excelente, mas é rápido. Se trocar para SDXL via LCM-LoRA, https://huggingface.co/latent-consistency talvez gere resultados melhores, mas a partir daí fica mais difícil e você começa a encontrar aqueles crashes enigmáticos mencionados antes. É o ponto em que passa a exigir trabalho de verdade
    Meu ambiente é 4090/3990x/CUDA 12.2/debian sid, e pode variar conforme o ambiente

  • Como funciona a demo em que a personagem feminina se move para dentro e fora do quadro? É ControlNet?

    • É entrada de vídeo. Segundo o texto, o filtro de similaridade estocástico reduz a carga de processamento da GPU ao diminuir as transformações quando há pouca mudança em relação ao frame anterior na entrada de vídeo. Os frames vermelhos no GIF acima são esse exemplo
    • Há uma issue aberta no GitHub para adicionar suporte a ControlNet, então não parece ser ControlNet. Parece ser simplesmente img2img usando prompt e escala rcfg
    • Então isso significa que a esquerda é a imagem original e a direita é a imagem resultante?
  • Qual é o fps em Apple Silicon?

    • É 0, porque não há suporte a MPS
      No entanto, na mesma faixa de preço hoje, considerando recondicionado por cerca de US$ 1.800, um M1 Max Studio com 64 GB é cerca de 13 vezes mais lento do que uma RTX 4090 de 24 GB em IA generativa com SD1.5 e SDXL
    • Estou rodando SDXL Turbo no DrawThings em um M1 Pro com 32 GB de RAM
      Uma imagem 512x512 com 5 passos é gerada em 5 segundos. Não uso refiner, upscaler nem restauração facial
      Pelo que sei, o DrawThings ainda não foi otimizado para SDXL Turbo nem para geração em pipeline
      Como referência, se eu criar uma imagem 2k x 2k com 50 passos usando SDXL Base+Refiner e restauração facial ativada, leva cerca de 120 segundos
    • Acho que pelo menos 1/8 deve ser possível, mas seria incrível se rodasse a pelo menos 24 fps na Apple. Talvez seja possível usando alguma interpolação
      Especialmente se for em estilo anime, que basicamente desenha uma imagem a cada 2 frames, talvez 12 fps já dê para aguentar
  • Existe algum vídeo que dê para assistir em algum lugar?