Uma porta MLX de fluxo com base na implementação dos difusores HuggingFace.
Execute os poderosos modelos de fluxo da Black Forest Labs localmente no seu Mac!
O MFLUX é uma porta de linha a linha da implementação do fluxo na biblioteca HuggingFace Difusers para a Apple MLX. O MFLUX é propositadamente mantido mínimo e explícito - as arquiteturas de rede são codificadas e nenhum arquivo de configuração é usado, exceto para os tokenizadores. O objetivo é ter uma pequena base de código com o objetivo único de expressar esses modelos (evitando muitas abstrações). Embora a legibilidade das prioridades do MFLUX sobre a generalidade e o desempenho, ela ainda pode ser bastante rápida e ainda mais rápido.
Todos os modelos são implementados do zero no MLX e apenas os tokenizadores são usados através da biblioteca HuggingFace Transformers. Fora isso, existem apenas dependências mínimas, como Numpy e travesseiro, para o pós-processamento de imagem simples.
Para os usuários, a maneira mais fácil de instalar o MFLUX é usar uv tool
: se você instalou uv
, simplesmente:
uv tool install --upgrade mflux
Para obter os executáveis da linha de comando mflux-generate
e Related. Você pode pular para os guias de uso abaixo.
O codificador T5 depende da peça de frase, que não possui um artefato de roda instalável para o Python 3.13 em novembro de 2024. Até o Google publicar uma roda de 3.13, você precisa construir sua própria roda com instruções oficiais de construção ou para sua conveniência .whl
pré-construído pelo colaborador @Anthonywu. As etapas abaixo devem funcionar para a maioria dos desenvolvedores, embora seu sistema possa variar.
uv venv --python 3.13
python -V # e.g. Python 3.13.0rc2
source .venv/bin/activate
# for your convenience, you can use the contributor wheel
uv pip install https://github.com/anthonywu/sentencepiece/releases/download/0.2.1-py13dev/sentencepiece-0.2.1-cp313-cp313-macosx_11_0_arm64.whl
# enable the pytorch nightly
uv pip install --pre --extra-index-url https://download.pytorch.org/whl/nightly -e .
mkdir -p mflux && cd mflux && python3 -m venv .venv && source .venv/bin/activate
Isso cria e ativa um ambiente virtual na pasta mflux
. Depois disso, instale o mflux via PIP:
pip install -U mflux
git clone [email protected]:filipstrand/mflux.git
make install
make test
make lint
Recomendado e make format
recomendado instala e usa ruff
. Você pode configurar seu editor/IDE para fins/formato automaticamente ou usar nossos make
fornecidos:make format
- formato seu códigomake lint
- mostra seus erros e avisos de fiapos, mas não conserta automaticamentemake check
- via ganchos pre-commit
, formate seu código e tentativas de corrigir automaticamente erros de fiaposruff
sobre usos avançados Execute o comando mflux-generate
especificando um prompt e o modelo e alguns argumentos opcionais. Por exemplo, aqui usamos uma versão quantizada do modelo schnell
para 2 etapas:
mflux-generate --model schnell --prompt " Luxury food photograph " --steps 2 --seed 2 -q 8
Este exemplo usa o modelo dev
mais poderoso com 25 etapas de tempo:
mflux-generate --model dev --prompt " Luxury food photograph " --steps 25 --seed 2 -q 8
Por padrão, os arquivos do modelo são baixados para a pasta .cache
no seu diretório inicial. Por exemplo, na minha configuração, o caminho é assim:
/Users/filipstrand/.cache/huggingface/hub/models--black-forest-labs--FLUX.1-dev
Para alterar esse comportamento padrão, você pode fazê -lo modificando a variável de ambiente HF_HOME
. Para obter mais detalhes sobre como ajustar essa configuração, consulte a documentação do Hugging Face .
Atualmente, o Flux.1-Dev requer acesso concedido ao seu repo Huggingface. Para solução de problemas, consulte o rastreador de problemas
--prompt
(Necessário, str
): Descrição do texto da imagem a ser gerada.
--model
ou -m
(necessário, str
): modelo a ser usado para a geração ( "schnell"
ou "dev"
).
--output
(opcional, str
, padrão: "image.png"
): saída de imagem de imagem.
--seed
(opcional, int
, padrão: None
): semente para geração de números aleatórios. O padrão é baseado no tempo.
--height
(opcional, int
, padrão: 1024
): altura da imagem de saída em pixels.
--width
(opcional, int
, padrão: 1024
): largura da imagem de saída em pixels.
--steps
(Opcional, int
, Padrão: 4
): Número de etapas de inferência.
--guidance
(opcional, float
, padrão: 3.5
): Escala de orientação (usada apenas para o modelo "dev"
).
--path
(Opcional, str
, Padrão: None
): caminho para um modelo local no disco.
--quantize
ou -q
(opcional, int
, padrão: None
): quantização (escolha entre 4
ou 8
).
--lora-paths
(opcional, [str]
, padrão: None
): os caminhos para os pesos da Lora.
--lora-scales
(opcional, [float]
, Padrão: None
): A escala para cada LORA respectiva (padrão será 1.0
se não for especificado e apenas um peso Lora é carregado.)
--metadata
(Opcional): Exporta um arquivo .json
que contém os metadados para a imagem com o mesmo nome. (Mesmo sem essa bandeira, os metadados da imagem são salvos e podem ser vistos usando exiftool image.png
.
--controlnet-image-path
(necessário, str
): caminho para a imagem local usada pelo ControlNet para orientar a geração de saída.
--controlnet-strength
(opcional, float
, padrão: 0.4
): grau de influência que a imagem de controle tem na saída. Varia de 0.0
(sem influência) a 1.0
(influência total).
--controlnet-save-canny
(opcional, bool, padrão: false): se definido, salva a imagem de referência de detecção de arestas astutas usada pelo ControlNet.
--init-image-path
(opcional, str
, padrão: None
): caminho local para a imagem inicial para geração de imagem para imagem.
--init-image-strength
(opcional, float
, padrão: 0.4
): controla a força da imagem inicial da imagem de saída. Um valor de 0.0
significa nenhuma influência. (O padrão é 0.4
)
--config-from-metadata
ou -C
(Opcional, str
): [Experimental] Caminho para um arquivo anterior salvo via --metadata
, ou um arquivo de configuração artesanal compatível em adesivo ao esquema Args esperado.
{
"$schema" : " http://json-schema.org/draft-07/schema# " ,
"type" : " object " ,
"properties" : {
"seed" : {
"type" : [ " integer " , " null " ]
},
"steps" : {
"type" : [ " integer " , " null " ]
},
"guidance" : {
"type" : [ " number " , " null " ]
},
"quantize" : {
"type" : [ " null " , " string " ]
},
"lora_paths" : {
"type" : [ " array " , " null " ],
"items" : {
"type" : " string "
}
},
"lora_scales" : {
"type" : [ " array " , " null " ],
"items" : {
"type" : " number "
}
},
"prompt" : {
"type" : [ " string " , " null " ]
}
}
}
{
"model" : " dev " ,
"seed" : 42 ,
"steps" : 8 ,
"guidance" : 3.0 ,
"quantize" : 4 ,
"lora_paths" : [
" /some/path1/to/subject.safetensors " ,
" /some/path2/to/style.safetensors "
],
"lora_scales" : [
0.8 ,
0.4
],
"prompt" : " award winning modern art, MOMA "
}
Ou, com o ambiente python correto ativo, crie e execute um script separado como o seguinte:
from mflux import Flux1 , Config
# Load the model
flux = Flux1 . from_alias (
alias = "schnell" , # "schnell" or "dev"
quantize = 8 , # 4 or 8
)
# Generate an image
image = flux . generate_image (
seed = 2 ,
prompt = "Luxury food photograph" ,
config = Config (
num_inference_steps = 2 , # "schnell" works well with 2-4 steps, "dev" works well with 20-25 steps
height = 1024 ,
width = 1024 ,
)
)
image . save ( path = "image.png" )
Para obter mais opções sobre como configurar o mflux, consulte Generate.py.
Esses números são baseados no modelo schnell
não quantizado , com a configuração fornecida no trecho de código abaixo. Para cronometrar sua máquina, execute o seguinte:
time mflux-generate
--prompt " Luxury food photograph "
--model schnell
--steps 2
--seed 2
--height 1024
--width 1024
Para descobrir as especificações da sua máquina (incluindo o número de núcleos da CPU, núcleos de GPU e memória, execute o seguinte comando:
system_profiler SPHardwareDataType SPDisplaysDataType
Dispositivo | M-Series | Usuário | Tempo relatado | Notas |
---|---|---|---|---|
Mac Studio | 2023 M2 Ultra | @awni | <15s | |
MacBook Pro | 2024 M4 Max (128 GB) | @ivanfioravanti | ~ 19s | |
MacBook Pro | 2023 M3 máx | @KarPathy | ~ 20s | |
- | 2023 M2 Max (96 GB) | @explorigin | ~ 25s | |
Mac mini | 2024 M4 Pro (64 GB) | @Stoobs | ~ 34s | |
Mac mini | 2023 M2 Pro (32 GB) | @Leekichko | ~ 54s | |
- | 2022 M1 Max (64 GB) | @Bosseparra | ~ 55s | |
MacBook Pro | 2023 M2 Max (32 GB) | @Filipstrand | ~ 70s | |
- | 2023 M3 Pro (36 GB) | @kush-gupp | ~ 80s | |
MacBook Pro | 2021 M1 Pro (32 GB) | @Filipstrand | ~ 160s | |
- | 2021 M1 Pro (16 GB) | @qw-in | ~ 175s | Pode congelar seu mac |
MacBook Air | 2020 M1 (8 GB) | @MbVillaverde | ~ 335s | Com a resolução 512 x 512 |
Observe que esses números incluem iniciar o aplicativo do Scratch, o que significa fazer E/S do modelo, definir/quantificar pesos etc. Se assumirmos que o modelo já está carregado, você poderá inspecionar os metadados da imagem usando exiftool image.png
e ver o total duração do loop de denoising (excluindo a incorporação de texto).
Esses parâmetros de referência não são muito científicos e se destinam apenas a fornecer números de estádio. Eles foram realizados durante diferentes momentos com diferentes versões MFLUX e MLX etc. Informações adicionais de hardware, como número de núcleos de GPU, dispositivo Mac etc. nem sempre são conhecidos.
Existe apenas uma única fonte de aleatoriedade ao gerar uma imagem: a matriz latente inicial. Nesta implementação, esse latente inicial é totalmente controlado deterministicamente pelo parâmetro seed
de entrada. No entanto, se importássemos uma instância fixa dessa matriz latente salva da implementação dos difusores, o MFLUX produzirá uma imagem idêntica à implementação dos difusores (assumindo um prompt fixo e usando as configurações de parâmetros padrão na configuração dos difusores).
As imagens abaixo ilustram essa equivalência. Em todos os casos, o modelo Schnell foi executado por 2 etapas de tempo. A implementação dos difusores foi executada no modo CPU. A precisão do MFLUX pode ser definida na classe Config. Normalmente, há uma diferença notável, mas muito pequena, na imagem final ao alternar entre a precisão de 16 bits e 32 bits.
Luxury food photograph
detailed cinematic dof render of an old dusty detailed CRT monitor on a wooden desk in a dim room with items around, messy dirty room. On the screen are the letters "FLUX" glowing softly. High detail hard surface render
photorealistic, lotr, A tiny red dragon curled up asleep inside a nest, (Soft Focus) , (f_stop 2.8) , (focal_length 50mm) macro lens f/2. 8, medieval wizard table, (pastel) colors, (cozy) morning light filtering through a nearby window, (whimsical) steam shapes, captured with a (Canon EOS R5) , highlighting (serene) comfort, medieval, dnd, rpg, 3d, 16K, 8K
A weathered fisherman in his early 60s stands on the deck of his boat, gazing out at a stormy sea. He has a thick, salt-and-pepper beard, deep-set blue eyes, and skin tanned and creased from years of sun exposure. He's wearing a yellow raincoat and hat, with water droplets clinging to the fabric. Behind him, dark clouds loom ominously, and waves crash against the side of the boat. The overall atmosphere is one of tension and respect for the power of nature.
Luxury food photograph of an italian Linguine pasta alle vongole dish with lots of clams. It has perfect lighting and a cozy background with big bokeh and shallow depth of field. The mood is a sunset balcony in tuscany. The photo is taken from the side of the plate. The pasta is shiny with sprinkled parmesan cheese and basil leaves on top. The scene is complemented by a warm, inviting light that highlights the textures and colors of the ingredients, giving it an appetizing and elegant look.
O Mflux suporta o fluxo em execução no modo quantizado de 4 bits ou 8 bits. A execução de uma versão quantizada pode acelerar bastante o processo de geração e reduzir o consumo de memória em vários gigabytes. Os modelos quantizados também ocupam menos espaço em disco.
mflux-generate
--model schnell
--steps 2
--seed 2
--quantize 8
--height 1920
--width 1024
--prompt " Tranquil pond in a bamboo forest at dawn, the sun is barely starting to peak over the horizon, panda practices Tai Chi near the edge of the pond, atmospheric perspective through the mist of morning dew, sunbeams, its movements are graceful and fluid — creating a sense of harmony and balance, the pond’s calm waters reflecting the scene, inviting a sense of meditation and connection with nature, style of Howard Terpning and Jessica Rossier "
Neste exemplo, os pesos são quantizados em tempo de execução - isso é conveniente se você não deseja salvar uma cópia quantizada dos pesos no disco, mas ainda deseja se beneficiar da possível velocidade de aceleração e redução de RAM pode trazer.
Ao selecionar o sinalizador --quantize
ou -q
para ser 4
, 8
ou removê -lo completamente, obtemos todas as três imagens acima. Como pode ser visto, há muito pouca diferença entre as imagens (especialmente entre os 8 bits e o resultado não quantizado). Os tempos de geração de imagens neste exemplo são baseados em uma máquina 2021 M1 Pro (32 GB). Embora as imagens sejam quase idênticas, existe uma aceleração ~ 2x executando a versão quantizada de 8 bits nessa máquina específica. Ao contrário da versão não quantizada, para a versão de 8 bits, o uso da memória de troca é drasticamente reduzido e a utilização da GPU é próxima de 100% durante toda a geração. Os resultados aqui podem variar entre diferentes máquinas.
Os tamanhos de modelo para schnell
e dev
em vários níveis de quantização são os seguintes:
4 bits | 8 bits | Original (16 bits) |
---|---|---|
9,85 GB | 18.16 GB | 33.73 GB |
A razão pela qual os tamanhos de pesos não são totalmente cortados pela metade é porque um pequeno número de pesos não é quantizado e mantido em total precisão.
Para salvar uma cópia local dos pesos quantizados, execute o comando mflux-save
como assim:
mflux-save
--path " /Users/filipstrand/Desktop/schnell_8bit "
--model schnell
--quantize 8
Observe que, ao salvar uma versão quantizada, você precisará dos pesos do Huggingface original.
Também é possível especificar adaptadores LORA ao salvar o modelo, por exemplo
mflux-save
--path " /Users/filipstrand/Desktop/schnell_8bit "
--model schnell
--quantize 8
--lora-paths " /path/to/lora.safetensors "
--lora-scales 0.7
Ao gerar imagens com um modelo como esse, nenhum adaptador LORA é necessário para ser especificado, pois ele já está assado nos pesos quantizados salvos.
Para gerar uma nova imagem a partir do modelo quantizado, basta fornecer um --path
para onde foi salva:
mflux-generate
--path " /Users/filipstrand/Desktop/schnell_8bit "
--model schnell
--steps 2
--seed 2
--height 1920
--width 1024
--prompt " Tranquil pond in a bamboo forest at dawn, the sun is barely starting to peak over the horizon, panda practices Tai Chi near the edge of the pond, atmospheric perspective through the mist of morning dew, sunbeams, its movements are graceful and fluid — creating a sense of harmony and balance, the pond’s calm waters reflecting the scene, inviting a sense of meditation and connection with nature, style of Howard Terpning and Jessica Rossier "
Nota: Ao carregar um modelo quantizado no disco, não há necessidade de passar o sinalizador -q
, pois podemos inferir isso nos metadados do peso.
Observe também: uma vez que tenhamos um modelo local (quantizado ou não) especificado através do argumento --path
, os modelos de cache do Huggingface não são necessários para iniciar o modelo. Em outras palavras, você pode recuperar o espaço de discos de 34 GB (por modelo), excluindo o modelo completo de 16 bits do cache Huggingface, se você escolher.
Se você não quiser baixar os modelos completos e quantizá-los você mesmo, os pesos de 4 bits estão disponíveis aqui para um download direto:
O MFLUX também suporta executar um modelo não quantizado diretamente de um local personalizado. No exemplo abaixo, o modelo é colocado em /Users/filipstrand/Desktop/schnell
:
mflux-generate
--path " /Users/filipstrand/Desktop/schnell "
--model schnell
--steps 2
--seed 2
--prompt " Luxury food photograph "
Observe que o sinalizador --model
deve ser definido ao carregar um modelo no disco.
Observe também que, diferentemente do uso da maneira típica de alias
de inicializar o modelo (que lida internamente que os recursos necessários são baixados), ao carregar um modelo diretamente do disco, exigimos que os modelos baixados pareçam o seguinte:
.
├── text_encoder
│ └── model.safetensors
├── text_encoder_2
│ ├── model-00001-of-00002.safetensors
│ └── model-00002-of-00002.safetensors
├── tokenizer
│ ├── merges.txt
│ ├── special_tokens_map.json
│ ├── tokenizer_config.json
│ └── vocab.json
├── tokenizer_2
│ ├── special_tokens_map.json
│ ├── spiece.model
│ ├── tokenizer.json
│ └── tokenizer_config.json
├── transformer
│ ├── diffusion_pytorch_model-00001-of-00003.safetensors
│ ├── diffusion_pytorch_model-00002-of-00003.safetensors
│ └── diffusion_pytorch_model-00003-of-00003.safetensors
└── vae
└── diffusion_pytorch_model.safetensors
Isso reflete como os recursos são colocados no repo Huggingface para o Flux.1. Os pesos do Huggingface, diferentemente dos quantizados exportados diretamente deste projeto, precisam ser processados de maneira um pouco diferente, e é por isso que exigimos essa estrutura acima.
Uma maneira de condicionar a geração de imagens é iniciando a partir de uma imagem existente e deixa o mflux produzir novas variações. Use o sinalizador --init-image-path
para especificar a imagem de referência e a --init-image-strength
para controlar quanto a imagem de referência deve orientar a geração. Por exemplo, dada a imagem de referência abaixo, o comando a seguir produziu a primeira imagem usando o desenho Lora:
mflux-generate
--prompt " sketching of an Eiffel architecture, masterpiece, best quality. The site is lit by lighting professionals, creating a subtle illumination effect. Ink on paper with very fine touches with colored markers, (shadings:1.1), loose lines, Schematic, Conceptual, Abstract, Gestural. Quick sketches to explore ideas and concepts. "
--init-image-path " reference.png "
--init-image-strength 0.3
--lora-paths Architectural_Sketching.safetensors
--lora-scales 1.0
--model dev
--steps 20
--seed 43
--guidance 4.0
--quantize 8
--height 1024
--width 1024
Como no ControlNet, esta técnica combina bem com os adaptadores LORA:
Nos exemplos acima dos seguintes Loras, são usados esboços, a foto de animação e a câmera de filmes de fluxo são usados.
Suporte ao Mlux Carregando adaptadores LORA treinados (o suporte real de treinamento está chegando).
O exemplo a seguir o Lora de @TheLastben:
mflux-generate --prompt " sandor clegane " --model dev --steps 20 --seed 43 -q 8 --lora-paths " sandor_clegane_single_layer.safetensors "
O exemplo a seguir é FLUX_1_DEV_LORA_SPOPER-CUTOUT LORA de @Norod78:
mflux-generate --prompt " pikachu, Paper Cutout Style " --model schnell --steps 4 --seed 43 -q 8 --lora-paths " Flux_1_Dev_LoRA_Paper-Cutout-Style.safetensors "
Observe que os pesos treinados da LORA são tipicamente treinados com uma palavra ou frase de gatilho . Por exemplo, neste último caso, a frase deve incluir a frase "estilo de recorte de papel" .
Observe também que os mesmos pesos da Lora podem funcionar bem com os modelos schnell
e dev
. Consulte o repositório LORA original para ver para que modo ele foi treinado.
Vários Loras podem ser enviados para combinar os efeitos dos adaptadores individuais. O exemplo a seguir combina ambos os Loras acima:
mflux-generate
--prompt " sandor clegane in a forest, Paper Cutout Style "
--model dev
--steps 20
--seed 43
--lora-paths sandor_clegane_single_layer.safetensors Flux_1_Dev_LoRA_Paper-Cutout-Style.safetensors
--lora-scales 1.0 1.0
-q 8
Apenas para ver a diferença, esta imagem exibe os quatro casos: um de ter os dois adaptadores totalmente ativos, parcialmente ativos e nenhum Lora. O exemplo acima também mostra o uso do sinalizador --lora-scales
.
Como diferentes serviços de ajuste fino podem usar diferentes implementações de fluxo, os pesos LORA correspondentes treinados nesses serviços podem ser diferentes um do outro. O objetivo do mflux é apoiar os mais comuns. A tabela a seguir mostra os formatos atuais suportados:
Suportado | Nome | Exemplo | Notas |
---|---|---|---|
✅ | Bfl | Civitai - impressionismo | Muitas coisas sobre civitai parecem funcionar |
✅ | Difusores | FLUX_1_DEV_LORA_SPOPER-CUTOUT estilo | |
XLABS-AI | Flux-Realismlora |
Para relatar formatos, exemplos ou outros sugestões adicionais relacionados ao suporte ao formato LORA, consulte a edição nº 47.
O MFLUX possui suporte ControlNet para um controle ainda mais fino da geração de imagens. Ao fornecer uma imagem de referência via --controlnet-image-path
e um parâmetro de força via --controlnet-strength
, você pode orientar a geração em direção à imagem de referência.
mflux-generate-controlnet
--prompt " A comic strip with a joker in a purple suit "
--model dev
--steps 20
--seed 1727047657
--height 1066
--width 692
-q 8
--lora-paths " Dark Comic - s0_8 g4.safetensors "
--controlnet-image-path " reference.png "
--controlnet-strength 0.5
--controlnet-save-canny
Este exemplo combina a imagem de referência do ControlNet com o fluxo da Lora Dark Comic .
generate-controlnet
. No momento, o controlnet usado é instantx/fluxo.1-dev-controlnet-canny, que foi treinado para o modelo dev
. Pode funcionar bem com schnell
, mas o desempenho não é garantido.
O ControlNet também pode funcionar bem junto com os adaptadores LORA. No exemplo abaixo, a mesma imagem de referência é usada como uma entrada do ControlNet com diferentes prompts e adaptadores LORA ativos.
export HF_HUB_DISABLE_PROGRESS_BARS=1
--args
alias mflux-dev='mflux-generate --model dev'
alias mflux-schnell='mflux-generate --model schnell --metadata'
Este projeto está licenciado sob a licença do MIT.