From 847404748fa8b0ea956fd09581cd60b5f27412e5 Mon Sep 17 00:00:00 2001 From: Filip Strand Date: Thu, 12 Jun 2025 09:01:07 +0200 Subject: [PATCH] Generalise in-context functionality (#203) Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> Co-authored-by: filipstrand --- .github/workflows/release.yml | 36 ++ CHANGELOG.md | 437 ++++++++++++++++++ README.md | 144 +++++- pyproject.toml | 4 +- scripts/release.py | 288 ++++++++++++ src/mflux/community/__init__.py | 3 - src/mflux/community/in_context/__init__.py | 0 .../flux_in_context_dev.py} | 8 +- .../in_context/flux_in_context_fill.py | 165 +++++++ .../community/in_context/utils/__init__.py | 0 .../utils}/in_context_loras.py | 30 ++ .../in_context/utils/in_context_mask_util.py | 88 ++++ .../community/in_context_lora/__init__.py | 6 - src/mflux/concept.py | 5 + src/mflux/concept_from_image.py | 5 + src/mflux/config/model_config.py | 30 +- .../dreambooth/lora_layers/lora_layers.py | 90 ++-- src/mflux/flux/flux_initializer.py | 8 +- src/mflux/flux_tools/fill/mask_util.py | 4 +- src/mflux/generate.py | 5 + src/mflux/generate_controlnet.py | 5 + src/mflux/generate_depth.py | 3 +- src/mflux/generate_fill.py | 3 +- src/mflux/generate_in_context_catvton.py | 80 ++++ ..._context.py => generate_in_context_dev.py} | 23 +- src/mflux/generate_in_context_edit.py | 103 +++++ src/mflux/generate_redux.py | 5 + src/mflux/ui/cli/parsers.py | 34 +- src/mflux/ui/defaults.py | 2 + src/mflux/weights/weight_handler.py | 69 ++- src/mflux/weights/weight_handler_lora.py | 6 + .../weight_handler_lora_huggingface.py | 4 +- tests/arg_parser/test_cli_argparser.py | 162 ++++++- .../image_generation_fill_test_helper.py | 3 +- .../image_generation_ic_edit_test_helper.py | 73 +++ ...image_generation_in_context_test_helper.py | 6 +- .../test_generate_image_in_context.py | 13 + tests/resources/ic_edit_reference.png | Bin 0 -> 171693 bytes 38 files changed, 1848 insertions(+), 102 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 CHANGELOG.md create mode 100644 scripts/release.py create mode 100644 src/mflux/community/in_context/__init__.py rename src/mflux/community/{in_context_lora/flux_in_context_lora.py => in_context/flux_in_context_dev.py} (95%) create mode 100644 src/mflux/community/in_context/flux_in_context_fill.py create mode 100644 src/mflux/community/in_context/utils/__init__.py rename src/mflux/community/{in_context_lora => in_context/utils}/in_context_loras.py (50%) create mode 100644 src/mflux/community/in_context/utils/in_context_mask_util.py delete mode 100644 src/mflux/community/in_context_lora/__init__.py create mode 100644 src/mflux/generate_in_context_catvton.py rename src/mflux/{generate_in_context.py => generate_in_context_dev.py} (79%) create mode 100644 src/mflux/generate_in_context_edit.py create mode 100644 tests/image_generation/helpers/image_generation_ic_edit_test_helper.py create mode 100644 tests/resources/ic_edit_reference.png diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e30d685 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,36 @@ +name: Create Release and Publish to PyPI + +on: + workflow_dispatch: + inputs: + version: + description: 'Release version (e.g., 0.8.1)' + required: true + type: string + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install requests + + - name: Run release script + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ github.event.inputs.version }} + TEST_PYPI_API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }} + PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }} + run: | + python scripts/release.py --version ${{ github.event.inputs.version }} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..1fe9415 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,437 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.8.0] - 2025-01-20 + +# MFLUX v.0.8.0 Release Notes + +## Experimental AI Features + +### πŸ‘— CatVTON (Virtual Try-On) +- **[EXPERIMENTAL]** Added virtual try-on capabilities using in-context learning via `mflux-generate-in-context-catvton` +- Support for person image, person mask, and garment image inputs for comprehensive virtual clothing try-on +- Automatic prompting for virtual try-on scenarios with optimized default prompts +- Side-by-side generation showing garment product shot alongside styled result +- AI-powered virtual clothing fitting with realistic lighting and fabric properties + +### ✏️ IC-Edit (In-Context Editing) +- **[EXPERIMENTAL]** Added natural language image editing capabilities via `mflux-generate-in-context-edit` +- Natural language image editing using simple text instructions like "make the hair black" or "add sunglasses" +- Automatic diptych template formatting for optimal editing results +- Optimal resolution auto-sizing for 512px width (the resolution IC-Edit was trained on) +- Specialized LoRA automatically downloaded and applied for enhanced editing capabilities + +## Enhanced Generation Control + +### πŸ”Ž Image Upscaling +- **Built-in upscaling capabilities**: Enhanced image quality and resolution enhancement for generated images +- Seamless integration with existing generation workflow +- Professional-grade upscaling for production-ready outputs + +## Interpretability research + +### 🧠 Concept Attention +- **Enhanced image generation control**: Fine-grained control over image generation focus areas using attention-based concepts +- Improved composition and subject handling for more precise artistic direction +- Advanced attention mechanisms for better understanding of prompt concepts + +## Workflow & Performance Improvements + +### πŸͺ« Battery Saver +- **Power management**: Automatic power optimization during extended generation sessions +- Configurable power-saving modes specifically designed for laptop users +- Smart resource management for long-running batch operations + +### πŸ“ Prompt File Support +- **File-based prompt input**: Batch operations via `--prompt-file` for large-scale generation projects +- Dynamic prompt updates for large batch generation workflows +- Support for external prompt management and automation systems + +### πŸ”„ Redux Function Balancing +- **Enhanced Redux capabilities**: Improved control over image-to-image transformation strength +- Better quality variations with adjustable parameters for more predictable results +- Refined Redux algorithm for more natural image variations + +## Developer Experience + +### πŸ”§ LORA_LIBRARY_PATH Improvements +- **Unix-style resource discovery**: Enhanced LoRA library path handling for better organization +- Improved path handling for LoRA weight discovery across multiple directories +- Better cross-platform compatibility for LoRA management + +### πŸ§ͺ Testing & Documentation +- New command-line arguments for both experimental features with comprehensive help +- Comprehensive argument parser tests for new functionality +- Updated documentation with experimental feature warnings and usage guidelines +- Added note about upcoming FLUX.1 Kontext model from Black Forest Labs + +## Architecture Improvements + +### πŸ“š Documentation Structure +- Refactored "In-Context LoRA" section to "In-Context Generation" with clear subcategories +- Enhanced documentation structure for better organization and user navigation +- Improved categorization of experimental vs stable features + +### ⚑ Performance Optimizations +- Updated MLX dependency to latest version for improved performance and stability +- Removed PyTorch dependency for DepthPro model, significantly reducing installation requirements +- Streamlined dependencies for faster installation and reduced disk usage + +## Experimental Notice + +⚠️ **Important**: CatVTON and IC-Edit features are experimental and may be removed or significantly changed in future updates. These features represent cutting-edge AI capabilities that are still under active development. + +## Contributors + +Special thanks to the following contributors for their exceptional work since v0.7.1: +- **Anthony Wu (@anthonywu)**: Battery Saver implementation, Prompt File Support, LORA_LIBRARY_PATH improvements +- **Alessandro (@alessandro)**: Redux Function Balancing enhancements +- **Filip Strand (@filipstrand)**: Core development, experimental features integration, infrastructure improvements + +## [0.7.1] - 2025-05-06 + +# MFLUX v.0.7.1 Release Notes + +## New Features + +### 🎭 Multi-LoRA Support +- **Multiple LoRA Loading**: Added support for loading multiple LoRA adapters simultaneously when using the in-context feature +- Enhanced creative flexibility by combining multiple artistic styles in a single generation +- Reference: [GitHub Issue #178](https://github.com/filipstrand/mflux/issues/178) + +## [0.7.0] - 2025-04-25 +# MFLUX v.0.7.0 Release Notes + +## Major New Features + +### πŸ–ŒοΈ FLUX.1 Tools | Fill + +- Added support for the FLUX.1-Fill model for inpainting and outpainting +- Introduced `mflux-generate-fill` command-line tool for selective image editing +- Implemented interactive mask creation tool to easily mark areas for regeneration +- Added outpainting capabilities with customizable canvas expansion +- Includes helper tools for creating outpaint image canvases and masks + +### πŸ” FLUX.1 Tools | Depth + +- Added support for the FLUX.1-Depth model for depth-conditioned image generation +- Implemented Apple's ML Depth Pro model in MLX for state-of-the-art depth map extraction +- Added `mflux-generate-depth` and `mflux-save-depth` command-line tools +- Added ability to use either auto-generated depth maps or custom depth maps + +### πŸ”„ FLUX.1 Tools | Redux + +- Added Redux tool as a new image variation technique +- Implemented a different approach compared to standard image-to-image generation +- Uses image embedding joined with T5 text encodings for more natural variations +- Added Redux-specific weight handlers and initialization + +## New Models + +### πŸ”Ž Apple ML Depth Pro + +- Added native MLX implementation of Apple's ML Depth Pro model for both separate use, and as a part of the Depth tool functionality + +### πŸ–ΌοΈ Google SigLIP Vision Transformer + +- Added SigLIP vision model for the Redux functionality + +## Architecture Improvements + +### πŸ’Ύ Weight Management Improvements + +- Added support for saving MFLUX version information in model metadata + +### 🧠 Memory Optimization + +- Additional improvements to the `--low-ram` option +- Better memory management for image generation models + +## Contributors + +- @anthonywu +- @ssakar +- @akx + +## [0.6.2] - 2025-03-13 + +# MFLUX v.0.6.2 Release Notes + +## Bug Fixes + +### πŸ’Ύ Model Saving Fix +- **Fixed local model saving**: Resolved bug preventing users from saving models locally with `mflux-save` +- Restored full functionality for local model storage and management + +## [0.6.1] - 2025-03-11 + +# MFLUX v.0.6.1 Release Notes + +## Bug Fixes + +### πŸ›‘ Image Generation Interruption +- **Fixed interruption flow**: Properly handles interruptions during image generation, ensuring graceful stops even when no callbacks are registered +- **Keyboard interrupt handling**: Ensures image generation can be stopped via Ctrl+C in all diffusion model variants (standard Flux, ControlNet, and In-Context LoRA) +- Relocated `StopImageGenerationException` from stepwise handler to main generation functions for more robust interruption system + +## Test Stability Improvements + +### πŸ§ͺ Test Reliability +- **Fixed sporadic test failures**: Resolved intermittent failures in auto-seeds test case when using random seed count of 1 +- Improved test consistency and reliability + +## Code Quality Improvements + +### πŸ”§ Code Standards +- **Formatting and linting fixes**: Fixed various formatting issues that were missed in the v0.6.0 release +- Enhanced code consistency and maintainability + +## [0.6.0] - 2025-03-05 +# MFLUX v.0.6.0 Release Notes + +## Major New Features + +### 🌐 Third-Party HuggingFace Model Support +- Comprehensive ModelConfig refactor to support compatible HuggingFace dev/schnell models +- Added ability to use models like `Freepik/flux.1-lite-8B-alpha` and `shuttleai/shuttle-3-diffusion` +- New `--base-model` parameter to specify which base architecture (dev or schnell) a third-party model is derived from +- Maintains backward compatibility while opening up the ecosystem to community-created models + +### 🎭 In-Context LoRA +- Added support for In-Context LoRA, a powerful technique that allows you to generate images in a specific style based on a reference image without requiring model fine-tuning +- Introduced a new command-line tool: `mflux-generate-in-context` +- Includes 10 pre-defined styles from the Hugging Face ali-vilab/In-Context-LoRA repository +- Detailed documentation on how to use this feature effectively with prompting tips and best practices + +### πŸ”Œ Automatic LoRA Downloads +- Added ability to automatically download LoRAs from Hugging Face when specified by repository ID +- Simplifies workflow by eliminating the need to manually download LoRA files before use + +### 🧠 Memory Optimizations +- Added `--low-ram` option to reduce GPU memory usage by constraining the MLX cache size and releasing text encoders and transformer components after use +- Implemented memory saver for ControlNet to reduce RAM requirements +- General memory usage optimizations throughout the codebase + +### πŸ—œοΈ Enhanced Quantization Options +- Added support for 3-bit and 6-bit quantization (requires mlx > v0.21.0) +- Expanded quantization options now include 3, 4, 6, and 8-bit precision + +## ⚠️Breaking changes + +Previously saved quantized models will not work for v.0.6.0 and later. See #149 for more details. + +## Interface Improvements + +### πŸ”§ Modified Parameters + +- The previous `--init-image-path` parameter is now `--image-path` +- The previous `--init-image-strength` parameter is now `--image-strength` + +### πŸ–ΌοΈ Image Generation Enhancements +- Added `--auto-seeds` option to generate multiple images with random seeds in a single command +- Added option to override previously saved test images +- Added `--controlnet-save-canny` option to save the Canny edge detection reference image used by ControlNet +- Improved handling of edge cases for img2img generation + +### πŸ”„ Callback System +- Implemented a general callback mechanism for more flexible image generation pipelines +- Added support for before-loop callbacks to accept latents +- Enhanced StepwiseHandler to include initial latent + +## Architecture Improvements + +### πŸ—οΈ Code Refactoring +- Removed 'init' prefix for a more general interface +- Removed `ConfigControlnet` - the `controlnet_strength` attribute is now on `Config` +- Simplified quantization by removing unnecessary class predicates +- Refactored model configuration system +- Refactored transformer blocks for better maintainability +- Unified attention mechanism in single and joint attention blocks +- Added support for variable numbers of transformer blocks +- Optimized with fast SDPA (Scaled Dot-Product Attention) +- Added PromptCache for small optimization when generating with repeated prompts + +### 🧰 Developer Tools +- Added Batch Image Renamer tool as an isolated uv run script +- Added descriptive comments for attention computations + +## Compatibility Updates +- Updated to support the latest mlx version +- Fixed compatibility issues with HuggingFace dev/schnell models + +## Bug Fixes +- Fixed handling of edge cases for img2img generation +- Various small fixes and improvements throughout the codebase + + +## Contributors + +- @anthonywu +- @ssakar +- @azrahello +- @DanaCase + +## [0.5.1] - 2024-12-23 + +# MFLUX v.0.5.1 Release Notes + +## Bug Fixes + +### πŸ”§ LoRA Loading Fix +- **Quantized model LoRA compatibility**: Fixed critical bug where locally saved quantized models failed to set LoRA weights +- Users can now successfully combine local quantized models with external LoRA adapters +- Improved reliability for advanced workflows combining quantization and LoRA fine-tuning + +## [0.5.0] - 2024-12-22 + +# MFLUX v.0.5.0 Release Notes + +## Major New Features + +### πŸŽ›οΈ DreamBooth Fine-tuning +- **DreamBooth support**: Introduced V1 of fine-tuning support in MFLUX +- Enables custom model training for personalized image generation +- Full fine-tuning pipeline with training configuration options + +## Architecture Improvements + +### πŸ”§ Weight Management Overhaul +- **Rewritten LoRA handling**: Completely rewritten LoRA weight handling system +- Improved performance and reliability for LoRA operations +- Better support for complex LoRA workflows + +## Developer Experience + +### πŸ§ͺ Testing & Quality +- **Enhanced test coverage**: Added comprehensive tests for new and existing features +- Multi-LoRA testing support +- Local model saving test coverage + +### πŸ“Š New Dependencies +- **Matplotlib integration**: Added matplotlib for visualizing training loss during fine-tuning +- **TOML support**: Added TOML library for better handling of MFLUX version metadata +- Enhanced configuration management + +## [0.4.1] - 2024-10-29 + +# MFLUX v.0.4.1 Release Notes + +## Bug Fixes + +### πŸ› Image Generation Fixes +- **Img2img resolution fix**: Fixed img2img functionality for non-square image resolutions +- Improved compatibility with various aspect ratios + +## [0.4.0] - 2024-10-28 + +# MFLUX v.0.4.0 Release Notes + +## Major New Features + +### πŸ–ΌοΈ Image-to-Image Generation +- **Img2Img Support**: Introduced the ability to generate images based on an initial reference image +- Transform existing images using AI-powered generation techniques +- Control the strength of transformation to balance between original image preservation and creative generation +- Perfect for iterating on designs and creating variations of existing artwork + +### πŸ“Š Metadata-Driven Generation +- **Image Generation from Metadata**: Added support to generate images directly from provided metadata files +- Streamlined workflow for recreating images with specific parameters +- Enhanced reproducibility for professional and research workflows +- Automated parameter loading from previously generated images + +### πŸ” Real-time Generation Monitoring +- **Progressive Step Output**: Optionally output each step of the image generation process for real-time monitoring +- Visual feedback during generation for better understanding of the AI process +- Debug and fine-tune generation parameters by observing intermediate steps +- Educational tool for understanding diffusion model progression + +## Developer Experience Improvements + +### πŸ› οΈ Enhanced Command-Line Interface +- **Improved argument handling**: Enhanced parsing and validation for command-line arguments +- Better error messages and user guidance for parameter configuration +- More intuitive command structure for complex generation workflows + +### πŸ§ͺ Testing & Quality Assurance +- **Automated Testing**: Added comprehensive automatic tests for image generation and command-line argument handling +- Improved reliability and stability for all generation modes +- Continuous integration testing for better code quality + +### πŸ”§ Development Workflow +- **Pre-Commit Hooks**: Integrated pre-commit hooks with `ruff`, `isort`, and typo checks for better code consistency +- Enhanced developer experience with automated code quality checks +- Streamlined contribution process for open source development + +## [0.3.0] - 2024-09-24 + +# MFLUX v.0.3.0 Release Notes + +## Major New Features + +### πŸ•ΉοΈ ControlNet Support +- **ControlNet Canny support**: Added Canny edge detection ControlNet functionality for precise image control +- Enhanced control over image generation with edge-guided conditioning + +## Model Export Improvements + +### πŸ“¦ Advanced Model Export +- **Quantized model export with LoRA**: Added ability to export quantized models with LoRA weights baked in +- Streamlined deployment for fine-tuned models + +## Developer Experience + +### πŸ› οΈ Development Tools +- **Enhanced development workflow**: Improved developer experience with uv, ruff, makefile, pre-commit hooks +- Better code quality tools and automated checks +- Streamlined contribution process + +## Legal & Licensing + +### βš–οΈ Open Source License +- **Official MIT license**: Established clear open source licensing for the project +- Legal clarity for users and contributors + +## [0.2.1] - 2024-09-14 + +# MFLUX v.0.2.1 Release Notes + +## Improvements + +### πŸ”§ LoRA Enhancements +- **Enhanced LoRA support**: Improved compatibility and performance for LoRA weight loading +- Better integration with existing workflows +- Refined handling of LoRA adapters + +## [0.2.0] - 2024-09-07 + +# MFLUX v.0.2.0 Release Notes + +## Major Milestone + +### πŸš€ Official PyPI Release +- **First official PyPI release**: `pip install mflux` - making MFLUX easily installable for everyone +- Big thanks to @deto for letting us have the "mflux" name on PyPI! + +## New Features + +### 🎨 Core Image Generation +- **Command-line tools**: Introduced dedicated commands for better user experience + - `mflux-generate` for generating images + - `mflux-save` for saving quantized models to disk +- **πŸ—œοΈ Quantization support**: Added support for quantized models with 4-bit and 8-bit precision +- **LoRA weights**: Added support for loading trained LoRA (Low-Rank Adaptation) weights +- **Automatic metadata**: Images now automatically save metadata when generated + +## Developer Experience + +### πŸ“¦ Distribution +- Official packaging and distribution through PyPI +- Simplified installation process for end users +- Professional project structure and naming \ No newline at end of file diff --git a/README.md b/README.md index 03c2545..a96545f 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Run the powerful [FLUX](https://blackforestlabs.ai/#get-flux) models from [Black * [Multi-LoRA](#multi-lora) * [LoRA Library Path](#lora-library-path) * [Supported LoRA formats (updated)](#supported-lora-formats-updated) -- [🎭 In-Context LoRA](#-in-context-lora) +- [🎭 In-Context Generation](#-in-context-generation) * [Available Styles](#available-styles) * [How It Works](#how-it-works) * [Tips for Best Results](#tips-for-best-results) @@ -230,7 +230,35 @@ The `mflux-generate-in-context` command supports most of the same arguments as ` - **`--lora-style`** (optional, `str`, default: `None`): The style to use for In-Context LoRA generation. Choose from: `couple`, `storyboard`, `font`, `home`, `illustration`, `portrait`, `ppt`, `sandstorm`, `sparklers`, or `identity`. -See the [In-Context LoRA](#-in-context-lora) section for more details on how to use this feature effectively. +See the [In-Context Generation](#-in-context-generation) section for more details on how to use this feature effectively. + +#### πŸ“œ CatVTON Command-Line Arguments + +The `mflux-generate-in-context-catvton` command supports most of the same arguments as `mflux-generate`, with these specific parameters: + +- **`--person-image`** (required, `str`): Path to the person image who will "wear" the garment. + +- **`--person-mask`** (required, `str`): Path to a binary mask image indicating where the garment should be applied on the person. + +- **`--garment-image`** (required, `str`): Path to the garment image to be virtually worn. + +- **`--save-full-image`** (optional, flag): Additionally save the full side-by-side image containing both the garment reference and the result. + +See the [CatVTON (Virtual Try-On)](#-catvton-virtual-try-on) section for more details on this feature. + +#### πŸ“œ IC-Edit Command-Line Arguments + +The `mflux-generate-in-context-edit` command supports most of the same arguments as `mflux-generate`, with these specific parameters: + +- **`--reference-image`** (required, `str`): Path to the reference image to be edited. + +- **`--instruction`** (optional, `str`): Simple text instruction describing the desired edit (e.g., "make the hair black"). This will be automatically formatted as a diptych template. Either `--instruction` or `--prompt` is required. + +- **`--save-full-image`** (optional, flag): Additionally save the full side-by-side image showing the original and edited versions. + +**Note**: The IC-Edit tool automatically downloads and applies the required LoRA, and optimizes the resolution to 512px width for best results. + +See the [IC-Edit (In-Context Editing)](#-ic-edit-in-context-editing) section for more details on this feature. #### πŸ“œ Redux Tool Command-Line Arguments @@ -842,9 +870,15 @@ To report additional formats, examples or other any suggestions related to LoRA --- -### 🎭 In-Context LoRA +### 🎭 In-Context Generation -In-Context LoRA is a powerful technique that allows you to generate images in a specific style based on a reference image, without requiring model fine-tuning. This approach uses specialized LoRA weights that enable the model to understand and apply the visual context from your reference image to a new generation. +In-Context Generation is a powerful collection of techniques that allows you to generate images based on reference images and context, without requiring model fine-tuning. MFLUX supports multiple in-context approaches, each designed for specific use cases ranging from style transfer to virtual try-on and image editing. + +**Note**: Black Forest Labs has announced [FLUX.1 Kontext](https://bfl.ai/models/flux-kontext), a new model suite designed specifically for text-and-image-driven generation and editing with advanced in-context capabilities. This official model may replace existing third-party implementations in the future. FLUX.1 Kontext offers character consistency, local editing, style reference, and interactive speed optimizations. The dev variant is coming soon as an open-weights model. + +#### 🎨 In-Context LoRA + +In-Context LoRA allows you to generate images in a specific style based on a reference image. This approach uses specialized LoRA weights that enable the model to understand and apply the visual context from your reference image to a new generation. This feature is based on the [In-Context LoRA for Diffusion Transformers](https://github.com/ali-vilab/In-Context-LoRA) project by Ali-ViLab. @@ -854,8 +888,7 @@ To use In-Context LoRA, you need: 1. A reference image 2. A style LoRA (optional - the in-context ability works without LoRAs, but they can significantly enhance the results) - -#### Available Styles +##### Available Styles MFLUX provides several pre-defined styles from the [Hugging Face ali-vilab/In-Context-LoRA repository](https://huggingface.co/ali-vilab/In-Context-LoRA) that you can use with the `--lora-style` argument: @@ -872,7 +905,7 @@ MFLUX provides several pre-defined styles from the [Hugging Face ali-vilab/In-Co | `sparklers` | Sparklers visual effect | | `identity` | Visual identity and branding design style | -#### How It Works +##### How It Works The In-Context LoRA generation creates a side-by-side image where: - The left side shows your reference image with noise applied @@ -882,8 +915,7 @@ The final output is automatically cropped to show only the right half (the gener ![image](src/mflux/assets/in_context_how_it_works.jpg) - -#### Prompting for In-Context LoRA +##### Prompting for In-Context LoRA For best results with In-Context LoRA, your prompt should describe both the reference image and the target image you want to generate. Use markers like `[IMAGE1]`, `[LEFT]`, or `[RIGHT]` to distinguish between the two parts. @@ -909,7 +941,7 @@ This prompt clearly describes both the reference image (after `[IMAGE1]`) and th **Important**: In the current implementation, the reference image is ALWAYS placed on the left side of the composition, and the generated image on the right side. When using marker pairs in your prompt, the first marker (e.g., `[IMAGE1]`, `[LEFT]`, `[REFERENCE]`) always refers to your reference image, while the second marker (e.g., `[IMAGE2]`, `[RIGHT]`, `[OUTPUT]`) refers to what you want to generate. -#### Tips for Best Results +##### Tips for Best Results 1. **Choose the right reference image**: Select a reference image with a clear composition and structure that matches your intended output. 2. **Adjust guidance**: Higher guidance values (7.0-9.0) tend to produce results that more closely follow your prompt. @@ -918,6 +950,95 @@ This prompt clearly describes both the reference image (after `[IMAGE1]`) and th 5. **Detailed prompting**: Be specific about both the reference image and your desired output in your prompt. 6. **Try without LoRA**: While LoRAs enhance the results, you can experiment without them to see the base in-context capabilities. +#### πŸ‘• CatVTON (Virtual Try-On) + +⚠️ **Experimental Feature**: CatVTON is an experimental feature and may be removed or significantly changed in future updates. + +CatVTON enables virtual try-on capabilities using in-context learning. This approach allows you to generate images of people wearing different garments by providing a person image, a person mask, and a garment image. + +The implementation is based on [@nftblackmagic/catvton-flux](https://github.com/nftblackmagic/catvton-flux) and uses the model weights from [xiaozaa/catvton-flux-beta](https://huggingface.co/xiaozaa/catvton-flux-beta) (approximately 24 GB download). + +##### How to Use CatVTON + +```sh +mflux-generate-in-context-catvton \ + --person-image "person.jpg" \ + --person-mask "person_mask.png" \ + --garment-image "garment.jpg" \ + --steps 20 \ + --seed 42 \ + --height 1024 \ + --width 1024 +``` + +##### Required Inputs + +- **Person Image**: A photo of the person who will "wear" the garment +- **Person Mask**: A binary mask indicating the areas where the garment should be applied +- **Garment Image**: The clothing item to be virtually worn + +##### CatVTON Features + +- **Automatic Prompting**: If no prompt is provided, CatVTON uses an optimized default prompt designed for virtual try-on scenarios +- **Side-by-Side Generation**: Creates a diptych showing the garment product shot alongside the styled result +- **Optimized for Clothing**: Specifically tuned for clothing and fashion applications +- **High-Quality Results**: Maintains realistic lighting, shadows, and fabric properties + +##### Tips for CatVTON + +1. **High-Quality Inputs**: Use high-resolution, well-lit images for best results +2. **Accurate Masks**: Ensure the person mask precisely covers the areas where the garment should appear +3. **Consistent Lighting**: Match lighting conditions between person and garment images when possible +4. **Garment Type**: Works best with clearly defined clothing items (shirts, dresses, jackets, etc.) + +#### ✏️ IC-Edit (In-Context Editing) + +⚠️ **Experimental Feature**: IC-Edit is an experimental feature and may be removed or significantly changed in future updates. + +IC-Edit provides intuitive image editing capabilities using natural language instructions. This approach automatically applies a specialized LoRA and generates edited versions of your reference image based on simple text instructions. + +The implementation is based on [@River-Zhang/ICEdit](https://github.com/River-Zhang/ICEdit). + +##### How to Use IC-Edit + +```sh +mflux-generate-in-context-edit \ + --reference-image "original.jpg" \ + --instruction "make the hair black" \ + --steps 20 \ + --seed 42 +``` + +##### Key Features + +- **Natural Language Instructions**: Use simple, descriptive instructions like "make the hair black", "add sunglasses", or "change the background to a beach" +- **Automatic Prompting**: Instructions are automatically wrapped in a diptych template for optimal results +- **Optimal Resolution**: Automatically resizes to 512px width (the resolution IC-Edit was trained on) while maintaining aspect ratio +- **Specialized LoRA**: Automatically downloads and applies the IC-Edit LoRA for enhanced editing capabilities + +##### IC-Edit Options + +You can use either `--instruction` for simple edits or `--prompt` for full control: + +```sh +# Using instruction (recommended) +mflux-generate-in-context-edit \ + --reference-image "photo.jpg" \ + --instruction "remove the glasses" + +# Using custom prompt (advanced) +mflux-generate-in-context-edit \ + --reference-image "photo.jpg" \ + --prompt "A diptych with two side-by-side images of the same scene. On the right, the scene is exactly the same as on the left but with a vintage filter applied" +``` + +##### Tips for IC-Edit + +1. **Clear Instructions**: Use specific, actionable instructions for best results +2. **Single Changes**: Focus on one edit at a time for more predictable results +3. **Reference Quality**: Higher quality reference images generally produce better edits +4. **Iterative Editing**: Use the output of one edit as input for the next to build complex changes + --- ### πŸ› οΈ Flux Tools @@ -1422,7 +1543,7 @@ This will generate the following image - Some LoRA adapters does not work. - Currently, the supported controlnet is the [canny-only version](https://huggingface.co/InstantX/FLUX.1-dev-Controlnet-Canny). - Dreambooth training currently does not support sending in training parameters as flags. -- In-Context LoRA currently only supports a left-right image setup (reference image on left, generated image on right). +- In-Context Generation features currently only support a left-right image setup (reference image on left, generated image on right). ### Optional Tool: Batch Image Renamer @@ -1457,7 +1578,6 @@ See `uv run tools/rename_images.py --help` for full CLI usage help. ### πŸ”¬ Cool research / features to support - [ ] [PuLID](https://github.com/ToTheBeginning/PuLID) -- [ ] [catvton-flux](https://github.com/nftblackmagic/catvton-flux) ### πŸŒ±β€ Related projects diff --git a/pyproject.toml b/pyproject.toml index e074fa6..3c884f9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,7 +57,9 @@ homepage = "https://github.com/filipstrand/mflux" [project.scripts] mflux-generate = "mflux.generate:main" mflux-generate-controlnet = "mflux.generate_controlnet:main" -mflux-generate-in-context = "mflux.generate_in_context:main" +mflux-generate-in-context = "mflux.generate_in_context_dev:main" +mflux-generate-in-context-edit = "mflux.generate_in_context_edit:main" +mflux-generate-in-context-catvton = "mflux.generate_in_context_catvton:main" mflux-generate-fill = "mflux.generate_fill:main" mflux-generate-depth = "mflux.generate_depth:main" mflux-generate-redux = "mflux.generate_redux:main" diff --git a/scripts/release.py b/scripts/release.py new file mode 100644 index 0000000..b9f5628 --- /dev/null +++ b/scripts/release.py @@ -0,0 +1,288 @@ +#!/usr/bin/env python3 + +import argparse +import os +import subprocess +import sys +from pathlib import Path +from typing import Optional + +import requests + + +class ReleaseManager: + def __init__(self, github_token: str): + self.github_token = github_token + self.github_repo = "filipstrand/mflux" + self.base_url = "https://api.github.com" + self.headers = { + "Authorization": f"token {github_token}", + "Accept": "application/vnd.github.v3+json", + "User-Agent": "MFLUX-Release-Script", + } + + @staticmethod + def extract_version_from_ref(github_ref: str) -> str: + if not github_ref.startswith("refs/tags/v."): + raise ValueError(f"Invalid GitHub ref format: {github_ref}") + return github_ref.replace("refs/tags/v.", "") + + @staticmethod + def extract_changelog_entry(version: str, changelog_path: Path = Path("CHANGELOG.md")) -> str: + import re + + if not changelog_path.exists(): + raise FileNotFoundError(f"Changelog file not found: {changelog_path}") + + content = changelog_path.read_text(encoding="utf-8") + + # Pattern to match version headers: ## [VERSION] + version_pattern = rf"^## \[{re.escape(version)}\].*$" + next_version_pattern = r"^## \[.*\].*$" + + lines = content.splitlines() + + # Find the start of the target version section + start_idx = None + for i, line in enumerate(lines): + if re.match(version_pattern, line): + start_idx = i + 1 # Start after the version header + break + + if start_idx is None: + raise ValueError(f"Version {version} not found in changelog") + + # Find the end of the section (next version header) + end_idx = len(lines) + for i in range(start_idx, len(lines)): + if re.match(next_version_pattern, lines[i]): + end_idx = i + break + + # Extract the content between version headers + entry_lines = lines[start_idx:end_idx] + + # Clean up: remove empty lines at start/end and strip trailing whitespace + while entry_lines and not entry_lines[0].strip(): + entry_lines.pop(0) + while entry_lines and not entry_lines[-1].strip(): + entry_lines.pop() + + entry_content = "\n".join(line.rstrip() for line in entry_lines) + + if not entry_content.strip(): + raise ValueError(f"No content found for version {version}") + + return entry_content + + def check_release_exists(self, tag_name: str) -> bool: + url = f"{self.base_url}/repos/{self.github_repo}/releases/tags/{tag_name}" + response = requests.get(url, headers=self.headers) + return response.status_code == 200 + + def create_github_release(self, tag_name: str, version: str, changelog_entry: str) -> dict: + url = f"{self.base_url}/repos/{self.github_repo}/releases" + + data = { + "tag_name": tag_name, + "name": f"Release {version}", + "body": changelog_entry, + "draft": False, + "prerelease": False, + } + + response = requests.post(url, json=data, headers=self.headers) + + if response.status_code == 201: + print(f"βœ… Successfully created GitHub release for {tag_name}") + return response.json() + else: + raise Exception(f"Failed to create GitHub release: {response.status_code} - {response.text}") + + @staticmethod + def run_command(cmd: list, description: str, check: bool = True) -> subprocess.CompletedProcess: + print(f"πŸ”„ {description}...") + print(f" Running: {' '.join(cmd)}") + + result = subprocess.run(cmd, capture_output=True, text=True, check=False) + + if result.returncode != 0 and check: + print(f"❌ {description} failed!") + print(f" stdout: {result.stdout}") + print(f" stderr: {result.stderr}") + raise Exception(f"Command failed: {' '.join(cmd)}") + + if result.stdout: + print(f" stdout: {result.stdout.strip()}") + + print(f"βœ… {description} completed successfully") + return result + + def build_package(self): + # Install build dependencies + self.run_command( + [sys.executable, "-m", "pip", "install", "--upgrade", "pip", "build", "twine"], + "Installing build dependencies", + ) + + # Build the package + self.run_command([sys.executable, "-m", "build"], "Building package") + + def publish_to_test_pypi(self, test_pypi_token: Optional[str]): + if not test_pypi_token: + print("⚠️ Test PyPI token not provided, skipping Test PyPI upload") + return + + env = os.environ.copy() + env["TWINE_USERNAME"] = "__token__" + env["TWINE_PASSWORD"] = test_pypi_token + + self.run_command( + [sys.executable, "-m", "twine", "upload", "--repository", "testpypi", "dist/*", "--verbose"], + "Publishing to Test PyPI", + ) + + @staticmethod + def publish_to_pypi(pypi_token: str): + env = os.environ.copy() + env["TWINE_USERNAME"] = "__token__" + env["TWINE_PASSWORD"] = pypi_token + + # Set environment variables for subprocess + cmd_env = os.environ.copy() + cmd_env.update(env) + + print("πŸ”„ Publishing to PyPI...") + print(f" Running: {sys.executable} -m twine upload dist/* --verbose") + + result = subprocess.run( + [sys.executable, "-m", "twine", "upload", "dist/*", "--verbose"], + capture_output=True, + text=True, + env=cmd_env, + check=False, + ) + + if result.returncode != 0: + print("❌ Publishing to PyPI failed!") + print(f" stdout: {result.stdout}") + print(f" stderr: {result.stderr}") + raise Exception("PyPI upload failed") + + if result.stdout: + print(f" stdout: {result.stdout.strip()}") + + print("βœ… Publishing to PyPI completed successfully") + + def release(self, version: str, test_pypi_token: Optional[str], pypi_token: str): + print("πŸš€ Starting MFLUX release process...") + + # Extract version + tag_name = f"v.{version}" + print(f"πŸ“¦ Releasing version: {version} (tag: {tag_name})") + + # Extract changelog + print("πŸ“ Extracting changelog entry...") + changelog_entry = self.extract_changelog_entry(version) + print(f" Found changelog entry ({len(changelog_entry)} characters)") + + # Check if release exists + print("πŸ” Checking if release already exists...") + if self.check_release_exists(tag_name): + print(f"⚠️ Release {tag_name} already exists, skipping GitHub release creation") + skip_github_release = True + else: + skip_github_release = False + + # Create GitHub release + if not skip_github_release: + self.create_github_release(tag_name, version, changelog_entry) + + # Build package + self.build_package() + + # Publish to Test PyPI + if not skip_github_release: # Only publish if this is a new release + self.publish_to_test_pypi(test_pypi_token) + + # Publish to PyPI + self.publish_to_pypi(pypi_token) + else: + print("⚠️ Skipping PyPI publishing since release already exists") + + print(f"πŸŽ‰ Release process completed successfully for version {version}!") + + +def main(): + parser = argparse.ArgumentParser(description="MFLUX Release Management") + parser.add_argument("--version", help="Release version (e.g., 0.8.0)") + parser.add_argument("--github-token", help="GitHub token") + parser.add_argument("--test-pypi-token", help="Test PyPI API token (optional)") + parser.add_argument("--pypi-token", help="PyPI API token") + parser.add_argument("--dry-run", action="store_true", help="Print what would be done without executing") + parser.add_argument("--show-changelog", help="Show changelog entry for a specific version (e.g., 0.8.0) and exit") + parser.add_argument("--markdown", action="store_true", help="Output changelog in markdown format (use with --show-changelog)") # fmt: off + + args = parser.parse_args() + + # Handle --show-changelog option + if args.show_changelog: + try: + changelog_entry = ReleaseManager.extract_changelog_entry(args.show_changelog) + + if args.markdown: + # Output as Markdown + print(f"# Release {args.show_changelog}\n") + print(changelog_entry) + print(f"\n---\n*Changelog entry: {len(changelog_entry)} characters*") + else: + # Output with separators (original format) + print(f"πŸ“ Changelog entry for version {args.show_changelog}:") + print("=" * 60) + print(changelog_entry) + print("=" * 60) + print(f"βœ… Found changelog entry ({len(changelog_entry)} characters)") + except (ValueError, FileNotFoundError) as e: + print(f"❌ Failed to extract changelog: {e}") + sys.exit(1) + return + + # Get values from args or environment variables + version = args.version or os.getenv("VERSION") + github_token = args.github_token or os.getenv("GITHUB_TOKEN") + test_pypi_token = args.test_pypi_token or os.getenv("TEST_PYPI_API_TOKEN") + pypi_token = args.pypi_token or os.getenv("PYPI_API_TOKEN") + + # Validate required parameters + if not version: + print("❌ Version is required (--version or VERSION env var)") + sys.exit(1) + + if not github_token: + print("❌ GitHub token is required (--github-token or GITHUB_TOKEN env var)") + sys.exit(1) + + if not pypi_token: + print("❌ PyPI token is required (--pypi-token or PYPI_API_TOKEN env var)") + sys.exit(1) + + if args.dry_run: + print("πŸ” DRY RUN MODE - would execute release process with:") + print(f" Version: {version}") + print(f" Has Test PyPI token: {bool(test_pypi_token)}") + print(f" Has PyPI token: {bool(pypi_token)}") + return + + try: + release_manager = ReleaseManager(github_token) + release_manager.release(version, test_pypi_token, pypi_token) + except (ValueError, FileNotFoundError, requests.RequestException) as e: + print(f"❌ Release failed: {e}") + sys.exit(1) + except Exception as e: # noqa: BLE001 + print(f"❌ Release failed with unexpected error: {e}") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/src/mflux/community/__init__.py b/src/mflux/community/__init__.py index fa233c3..e69de29 100644 --- a/src/mflux/community/__init__.py +++ b/src/mflux/community/__init__.py @@ -1,3 +0,0 @@ -""" -Third-party extensions and integrations for MFlux. -""" diff --git a/src/mflux/community/in_context/__init__.py b/src/mflux/community/in_context/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/mflux/community/in_context_lora/flux_in_context_lora.py b/src/mflux/community/in_context/flux_in_context_dev.py similarity index 95% rename from src/mflux/community/in_context_lora/flux_in_context_lora.py rename to src/mflux/community/in_context/flux_in_context_dev.py index f124ef5..07f2564 100644 --- a/src/mflux/community/in_context_lora/flux_in_context_lora.py +++ b/src/mflux/community/in_context/flux_in_context_dev.py @@ -19,7 +19,7 @@ from mflux.post_processing.generated_image import GeneratedImage from mflux.post_processing.image_util import ImageUtil -class Flux1InContextLoRA(nn.Module): +class Flux1InContextDev(nn.Module): vae: VAE transformer: Transformer t5_text_encoder: T5Encoder @@ -66,7 +66,7 @@ class Flux1InContextLoRA(nn.Module): ) # 2. Create the initial latents and keep the initial static noise for later blending - static_noise = Flux1InContextLoRA._create_in_context_latents(seed=seed, config=config) + static_noise = Flux1InContextDev._create_in_context_latents(seed=seed, config=config) latents = mx.array(static_noise) # 3. Encode the prompt @@ -102,8 +102,8 @@ class Flux1InContextLoRA(nn.Module): dt = config.sigmas[t + 1] - config.sigmas[t] latents += noise * dt - # 6.t Override left hand side of latents by linearly interpolating between latents and static noise - latents = Flux1InContextLoRA._update_latents( + # 6.t Override the left-hand side of latents by linearly interpolating between latents and static noise + latents = Flux1InContextDev._update_latents( t=t, config=config, latents=latents, diff --git a/src/mflux/community/in_context/flux_in_context_fill.py b/src/mflux/community/in_context/flux_in_context_fill.py new file mode 100644 index 0000000..454c25a --- /dev/null +++ b/src/mflux/community/in_context/flux_in_context_fill.py @@ -0,0 +1,165 @@ +import mlx.core as mx +from mlx import nn +from tqdm import tqdm + +from mflux.callbacks.callbacks import Callbacks +from mflux.community.in_context.utils.in_context_mask_util import InContextMaskUtil +from mflux.config.config import Config +from mflux.config.model_config import ModelConfig +from mflux.config.runtime_config import RuntimeConfig +from mflux.error.exceptions import StopImageGenerationException +from mflux.flux.flux_initializer import FluxInitializer +from mflux.latent_creator.latent_creator import LatentCreator +from mflux.models.text_encoder.clip_encoder.clip_encoder import CLIPEncoder +from mflux.models.text_encoder.prompt_encoder import PromptEncoder +from mflux.models.text_encoder.t5_encoder.t5_encoder import T5Encoder +from mflux.models.transformer.transformer import Transformer +from mflux.models.vae.vae import VAE +from mflux.post_processing.array_util import ArrayUtil +from mflux.post_processing.generated_image import GeneratedImage +from mflux.post_processing.image_util import ImageUtil + + +class FluxInContextFill(nn.Module): + vae: VAE + transformer: Transformer + t5_text_encoder: T5Encoder + clip_text_encoder: CLIPEncoder + + def __init__( + self, + model_config: ModelConfig, + quantize: int | None = None, + local_path: str | None = None, + lora_paths: list[str] | None = None, + lora_scales: list[float] | None = None, + ): + super().__init__() + FluxInitializer.init( + flux_model=self, + model_config=model_config, + quantize=quantize, + local_path=local_path, + lora_paths=lora_paths, + lora_scales=lora_scales, + ) + + def generate_image( + self, + seed: int, + prompt: str, + config: Config, + left_image_path: str, + right_image_path: str | None = None, + ) -> GeneratedImage: + # 0. Create a new runtime config based on the model type and input parameters + config = RuntimeConfig(config, self.model_config) + + # For in-context learning with side-by-side approach, double the width + original_width = config.width + config.width = original_width * 2 + + time_steps = tqdm(range(config.init_time_step, config.num_inference_steps)) + + # 1. Create the initial latents + latents = LatentCreator.create( + seed=seed, + height=config.height, + width=config.width, + ) + + # 2. Encode the prompt + prompt_embeds, pooled_prompt_embeds = PromptEncoder.encode_prompt( + prompt=prompt, + prompt_cache=self.prompt_cache, + t5_tokenizer=self.t5_tokenizer, + clip_tokenizer=self.clip_tokenizer, + t5_text_encoder=self.t5_text_encoder, + clip_text_encoder=self.clip_text_encoder, + ) + + # 3. Create the static masked latents + static_masked_latents = InContextMaskUtil.create_masked_latents( + vae=self.vae, + height=config.height, + width=config.width, + original_width=original_width, + left_image_path=left_image_path, + right_image_path=right_image_path, + mask_path=config.masked_image_path, + ) + + # (Optional) Call subscribers for beginning of loop + Callbacks.before_loop( + seed=seed, + prompt=prompt, + latents=latents, + config=config, + ) + + for t in time_steps: + try: + # 4.t Concatenate the updated latents with the static masked latents + hidden_states = mx.concatenate([latents, static_masked_latents], axis=-1) + + # 5.t Predict the noise + noise = self.transformer( + t=t, + config=config, + hidden_states=hidden_states, + prompt_embeds=prompt_embeds, + pooled_prompt_embeds=pooled_prompt_embeds, + ) + + # 6.t Take one denoise step + dt = config.sigmas[t + 1] - config.sigmas[t] + latents += noise * dt + + # (Optional) Call subscribers in-loop + Callbacks.in_loop( + t=t, + seed=seed, + prompt=prompt, + latents=latents, + config=config, + time_steps=time_steps, + ) + + # (Optional) Evaluate to enable progress tracking + mx.eval(latents) + + except KeyboardInterrupt: # noqa: PERF203 + Callbacks.interruption( + t=t, + seed=seed, + prompt=prompt, + latents=latents, + config=config, + time_steps=time_steps, + ) + raise StopImageGenerationException(f"Stopping image generation at step {t + 1}/{len(time_steps)}") + + # (Optional) Call subscribers after loop + Callbacks.after_loop( + seed=seed, + prompt=prompt, + latents=latents, + config=config, + ) + + # 7. Decode the latent array and return the full image + latents = ArrayUtil.unpack_latents(latents=latents, height=config.height, width=config.width) + decoded = self.vae.decode(latents) + return ImageUtil.to_image( + decoded_latents=decoded, + config=config, + seed=seed, + prompt=prompt, + quantization=self.bits, + lora_paths=self.lora_paths, + lora_scales=self.lora_scales, + image_path=right_image_path, + image_strength=config.image_strength, + masked_image_path=config.masked_image_path, + generation_time=time_steps.format_dict["elapsed"], + ) diff --git a/src/mflux/community/in_context/utils/__init__.py b/src/mflux/community/in_context/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/mflux/community/in_context_lora/in_context_loras.py b/src/mflux/community/in_context/utils/in_context_loras.py similarity index 50% rename from src/mflux/community/in_context_lora/in_context_loras.py rename to src/mflux/community/in_context/utils/in_context_loras.py index 0b7a26d..ec620c7 100644 --- a/src/mflux/community/in_context_lora/in_context_loras.py +++ b/src/mflux/community/in_context/utils/in_context_loras.py @@ -1,5 +1,7 @@ """Configuration for In-Context LoRAs from Hugging Face.""" +from mflux.weights.weight_handler_lora_huggingface import WeightHandlerLoRAHuggingFace + # Default Hugging Face repository for In-Context LoRAs LORA_REPO_ID = "ali-vilab/In-Context-LoRA" @@ -17,9 +19,37 @@ LORA_NAME_MAP = { "identity": "visual-identity-design.safetensors", } +# IC-Edit specific configuration +IC_EDIT_LORA_REPO_ID = "RiverZ/normal-lora" +IC_EDIT_LORA_FILENAME = "pytorch_lora_weights.safetensors" +IC_EDIT_LORA_SCALE = 1.0 + def get_lora_filename(simple_name: str) -> str: if simple_name not in LORA_NAME_MAP: valid_names = ", ".join(sorted(LORA_NAME_MAP.keys())) raise ValueError(f"Unknown LoRA name: {simple_name}. Valid names are: {valid_names}") return LORA_NAME_MAP[simple_name] + + +def prepare_ic_edit_loras(additional_lora_paths: list[str] | None = None) -> list[str]: + print(f"πŸ” Downloading IC-Edit LoRA from {IC_EDIT_LORA_REPO_ID}") + + # Download the required IC-Edit LoRA + ic_edit_lora_path = WeightHandlerLoRAHuggingFace.download_lora( + repo_id=IC_EDIT_LORA_REPO_ID, + lora_name=IC_EDIT_LORA_FILENAME, + ) + + # IC-Edit LoRA is always required and goes first + lora_paths = [ic_edit_lora_path] + + # Add any additional user-specified LoRAs + if additional_lora_paths: + lora_paths.extend(additional_lora_paths) + + print(f"βœ… IC-Edit LoRA ready: {ic_edit_lora_path}") + if len(lora_paths) > 1: + print(f"πŸ“‹ Additional LoRAs: {lora_paths[1:]}") + + return lora_paths diff --git a/src/mflux/community/in_context/utils/in_context_mask_util.py b/src/mflux/community/in_context/utils/in_context_mask_util.py new file mode 100644 index 0000000..33aff52 --- /dev/null +++ b/src/mflux/community/in_context/utils/in_context_mask_util.py @@ -0,0 +1,88 @@ +import mlx.core as mx + +from mflux.flux_tools.fill.mask_util import MaskUtil +from mflux.models.vae.vae import VAE +from mflux.post_processing.array_util import ArrayUtil +from mflux.post_processing.image_util import ImageUtil + + +class InContextMaskUtil: + @staticmethod + def create_masked_latents( + vae: VAE, + height: int, + width: int, + original_width: int, + left_image_path: str, + right_image_path: str | None, + mask_path: str, + ): + # Determine mode based on whether right_image_path is provided + is_pure_mode = right_image_path is None + + # Step 1: Load left image (reference) - always required + left_image = ImageUtil.scale_to_dimensions( + image=ImageUtil.load_image(left_image_path).convert("RGB"), + target_width=original_width, + target_height=height, + ) + left_array = ImageUtil.to_array(left_image) + + # Step 2: Handle right image based on mode + if is_pure_mode: + # Pure mode: create empty/noise for right side + right_array = mx.zeros_like(left_array) # or could use noise + else: + # Selective mode: load target image for right side + right_image = ImageUtil.scale_to_dimensions( + image=ImageUtil.load_image(right_image_path).convert("RGB"), + target_width=original_width, + target_height=height, + ) + right_array = ImageUtil.to_array(right_image) + + # Step 3: Determine the right-side mask based on mode + if is_pure_mode: + # Pure in-context: generate entire right side + mask_array = mx.ones((1, 1, height, original_width)) + else: + # Selective: use provided mask exactly + mask_image = ImageUtil.scale_to_dimensions( + image=ImageUtil.load_image(mask_path).convert("RGB"), + target_width=original_width, + target_height=height, + ) + mask_array = ImageUtil.to_array(mask_image, is_mask=True) + + # Step 4: Create concatenated inputs for in-context learning + # Layout: [LEFT_IMAGE] | [RIGHT_IMAGE] + concatenated_image = mx.concatenate([left_array, right_array], axis=3) + + # Layout: [NO_MASK] | [ACTUAL_MASK] + reference_mask = mx.zeros_like(mask_array) # Empty mask for reference (preserve fully) + concatenated_mask = mx.concatenate([reference_mask, mask_array], axis=3) + + # Step 5: Apply standard FLUX Fill processing to concatenated inputs + masked_concatenated_image = concatenated_image * (1 - concatenated_mask) + + # Encode and process exactly like MaskUtil.create_masked_latents + encoded_image = vae.encode(masked_concatenated_image) + encoded_image = ArrayUtil.pack_latents( + latents=encoded_image, + height=height, + width=width, + ) + + processed_mask = MaskUtil.reshape_mask( + the_mask=concatenated_mask, + height=height, + width=width, + ) + processed_mask = ArrayUtil.pack_latents( + latents=processed_mask, + height=height, + width=width, + num_channels_latents=64, + ) + + return mx.concatenate([encoded_image, processed_mask], axis=-1) diff --git a/src/mflux/community/in_context_lora/__init__.py b/src/mflux/community/in_context_lora/__init__.py deleted file mode 100644 index 9cb55e1..0000000 --- a/src/mflux/community/in_context_lora/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -""" -In-context LoRA implementation for MFlux. - -This module provides functionality for conditioning image generation using a reference image -directly in the latent space, without requiring model fine-tuning. -""" diff --git a/src/mflux/concept.py b/src/mflux/concept.py index 7e40fb7..c3bfa16 100644 --- a/src/mflux/concept.py +++ b/src/mflux/concept.py @@ -2,6 +2,7 @@ from mflux import Config, ModelConfig, StopImageGenerationException from mflux.callbacks.callback_manager import CallbackManager from mflux.community.concept_attention.flux_concept import Flux1Concept from mflux.error.exceptions import PromptFileReadError +from mflux.ui import defaults as ui_defaults from mflux.ui.cli.parsers import CommandLineParser from mflux.ui.prompt_utils import get_effective_prompt @@ -18,6 +19,10 @@ def main(): parser.add_concept_attention_arguments() args = parser.parse_args() + # 0. Set default guidance value if not provided by user + if args.guidance is None: + args.guidance = ui_defaults.GUIDANCE_SCALE + # 1. Load the concept attention model flux = Flux1Concept( model_config=ModelConfig.from_name(model_name=args.model, base_model=args.base_model), diff --git a/src/mflux/concept_from_image.py b/src/mflux/concept_from_image.py index 44a3280..a7683a1 100644 --- a/src/mflux/concept_from_image.py +++ b/src/mflux/concept_from_image.py @@ -2,6 +2,7 @@ from mflux import Config, ModelConfig, StopImageGenerationException from mflux.callbacks.callback_manager import CallbackManager from mflux.community.concept_attention.flux_concept_from_image import FluxConceptFromImage from mflux.error.exceptions import PromptFileReadError +from mflux.ui import defaults as ui_defaults from mflux.ui.cli.parsers import CommandLineParser from mflux.ui.prompt_utils import get_effective_prompt @@ -18,6 +19,10 @@ def main(): parser.add_concept_from_image_arguments() args = parser.parse_args() + # 0. Set default guidance value if not provided by user + if args.guidance is None: + args.guidance = ui_defaults.GUIDANCE_SCALE + # 1. Load the concept attention model flux = FluxConceptFromImage( model_config=ModelConfig.from_name(model_name=args.model, base_model=args.base_model), diff --git a/src/mflux/config/model_config.py b/src/mflux/config/model_config.py index df53186..e04d7ab 100644 --- a/src/mflux/config/model_config.py +++ b/src/mflux/config/model_config.py @@ -11,6 +11,7 @@ class ModelConfig: model_name: str, base_model: str | None, controlnet_model: str | None, + custom_transformer_model: str | None, num_train_steps: int, max_sequence_length: int, supports_guidance: bool, @@ -21,6 +22,7 @@ class ModelConfig: self.model_name = model_name self.base_model = base_model self.controlnet_model = controlnet_model + self.custom_transformer_model = custom_transformer_model self.num_train_steps = num_train_steps self.max_sequence_length = max_sequence_length self.supports_guidance = supports_guidance @@ -37,6 +39,11 @@ class ModelConfig: def dev_fill() -> "ModelConfig": return AVAILABLE_MODELS["dev-fill"] + @staticmethod + @lru_cache + def dev_fill_catvton() -> "ModelConfig": + return AVAILABLE_MODELS["dev-fill-catvton"] + @staticmethod @lru_cache def dev_depth() -> "ModelConfig": @@ -68,7 +75,7 @@ class ModelConfig: return AVAILABLE_MODELS["schnell"] def x_embedder_input_dim(self) -> int: - if self.alias == "dev-fill": + if self.alias and "dev-fill" in self.alias: return 384 if self.alias == "dev-depth": return 128 @@ -116,6 +123,7 @@ class ModelConfig: model_name=model_name, base_model=default_base.model_name, controlnet_model=default_base.controlnet_model, + custom_transformer_model=default_base.custom_transformer_model, num_train_steps=default_base.num_train_steps, max_sequence_length=default_base.max_sequence_length, supports_guidance=default_base.supports_guidance, @@ -130,6 +138,7 @@ AVAILABLE_MODELS = { model_name="black-forest-labs/FLUX.1-schnell", base_model=None, controlnet_model=None, + custom_transformer_model=None, num_train_steps=1000, max_sequence_length=256, supports_guidance=False, @@ -141,6 +150,7 @@ AVAILABLE_MODELS = { model_name="black-forest-labs/FLUX.1-dev", base_model=None, controlnet_model=None, + custom_transformer_model=None, num_train_steps=1000, max_sequence_length=512, supports_guidance=True, @@ -152,6 +162,7 @@ AVAILABLE_MODELS = { model_name="black-forest-labs/FLUX.1-Fill-dev", base_model=None, controlnet_model=None, + custom_transformer_model=None, num_train_steps=1000, max_sequence_length=512, supports_guidance=True, @@ -163,6 +174,7 @@ AVAILABLE_MODELS = { model_name="black-forest-labs/FLUX.1-Depth-dev", base_model=None, controlnet_model=None, + custom_transformer_model=None, num_train_steps=1000, max_sequence_length=512, supports_guidance=True, @@ -174,17 +186,31 @@ AVAILABLE_MODELS = { model_name="black-forest-labs/FLUX.1-Redux-dev", base_model=None, controlnet_model=None, + custom_transformer_model=None, num_train_steps=1000, max_sequence_length=512, supports_guidance=True, requires_sigma_shift=True, priority=3, ), + "dev-fill-catvton": ModelConfig( + alias="dev-fill-catvton", + model_name="black-forest-labs/FLUX.1-Fill-dev", + base_model=None, + controlnet_model=None, + custom_transformer_model="xiaozaa/catvton-flux-beta", + num_train_steps=1000, + max_sequence_length=512, + supports_guidance=True, + requires_sigma_shift=False, # Not sure why, but produced better results this way... + priority=6, + ), "dev-controlnet-canny": ModelConfig( alias="dev-controlnet-canny", model_name="black-forest-labs/FLUX.1-dev", base_model=None, controlnet_model="InstantX/FLUX.1-dev-Controlnet-Canny", + custom_transformer_model=None, num_train_steps=1000, max_sequence_length=512, supports_guidance=True, @@ -196,6 +222,7 @@ AVAILABLE_MODELS = { model_name="black-forest-labs/FLUX.1-schnell", base_model=None, controlnet_model="InstantX/FLUX.1-dev-Controlnet-Canny", + custom_transformer_model=None, num_train_steps=1000, max_sequence_length=256, supports_guidance=False, @@ -207,6 +234,7 @@ AVAILABLE_MODELS = { model_name="black-forest-labs/FLUX.1-dev", base_model=None, controlnet_model="jasperai/Flux.1-dev-Controlnet-Upscaler", + custom_transformer_model=None, num_train_steps=1000, max_sequence_length=512, supports_guidance=False, diff --git a/src/mflux/dreambooth/lora_layers/lora_layers.py b/src/mflux/dreambooth/lora_layers/lora_layers.py index 5ff3d9c..4969f7e 100644 --- a/src/mflux/dreambooth/lora_layers/lora_layers.py +++ b/src/mflux/dreambooth/lora_layers/lora_layers.py @@ -108,7 +108,7 @@ class LoRALayers: base_path=base_path, ) - if parts[1] == "single_transformer_blocks": + elif parts[1] == "single_transformer_blocks": LoRALayers._handle_single_transformer_blocks( weights=weights, scale=scale, @@ -117,8 +117,44 @@ class LoRALayers: base_path=base_path, ) + # Handle top-level transformer components like x_embedder, context_embedder, proj_out + elif len(parts) == 2 and parts[0] == "transformer": + LoRALayers._handle_top_level_component( + weights=weights, + scale=scale, + transformer=transformer, + lora_layers=lora_layers, + base_path=base_path, + component_name=parts[1], + ) + return lora_layers + @staticmethod + def _resolve_legacy_paths(module, module_name: str, attr_name: str, parts: list, block_idx: int) -> tuple: + # Handle legacy naming: ff.net.2 -> ff.linear2 + if module_name == "ff" and attr_name == "net" and len(parts) >= 6 and parts[5] == "2": + return getattr(module, "linear2"), f"transformer.transformer_blocks.{block_idx}.ff.linear2" + + # Handle attn.to_out.0 -> attn.to_out[0] (list access) + if module_name == "attn" and attr_name == "to_out" and len(parts) >= 6 and parts[5] == "0": + return module.to_out[0], f"transformer.transformer_blocks.{block_idx}.attn.to_out" + + # Default case + original_layer = getattr(module, attr_name) + if len(parts) == 6: + original_layer = original_layer[0] + return original_layer, ".".join(parts) + + @staticmethod + def _create_lora_layer(weights: dict, base_path: str, original_layer, scale: float): + lora_A = weights[f"{base_path}.lora_A"] + rank = lora_A.shape[1] + lora_layer = LoRALinear.from_linear(linear=original_layer, r=rank, scale=scale) + lora_layer.lora_A = lora_A + lora_layer.lora_B = weights[f"{base_path}.lora_B"] + return lora_layer + @staticmethod def _handle_transformer_blocks( weights: dict, scale: float, transformer: nn.Module, lora_layers: dict, base_path: str @@ -129,22 +165,19 @@ class LoRALayers: attr_name = parts[4] block = transformer.transformer_blocks[block_idx] module = getattr(block, module_name) - original_layer = getattr(module, attr_name) - if len(parts) == 6: - original_layer = original_layer[0] # Special case here + # Resolve legacy naming and get the actual layer and storage path + original_layer, storage_path = LoRALayers._resolve_legacy_paths( + module=module, + module_name=module_name, + attr_name=attr_name, + parts=parts, + block_idx=block_idx, + ) - # Create LoRA layer - lora_A = weights[f"{base_path}.lora_A"] - rank = lora_A.shape[1] - lora_layer = LoRALinear.from_linear(linear=original_layer, r=rank, scale=scale) - - # Set the weights - lora_layer.lora_A = weights[f"{base_path}.lora_A"] - lora_layer.lora_B = weights[f"{base_path}.lora_B"] - - # Store the layer - lora_layers[base_path] = lora_layer + # Create and store LoRA layer + lora_layer = LoRALayers._create_lora_layer(weights, base_path, original_layer, scale) + lora_layers[storage_path] = lora_layer @staticmethod def _handle_single_transformer_blocks( @@ -153,24 +186,25 @@ class LoRALayers: parts = base_path.split(".") block_idx = int(parts[2]) module_name = parts[3] + if len(parts) == 4: original_layer = getattr(transformer.single_transformer_blocks[block_idx], module_name) - elif len(parts) == 5: + else: attr_name = parts[4] block = transformer.single_transformer_blocks[block_idx] module = getattr(block, module_name) original_layer = getattr(module, attr_name) - # Create LoRA layer - lora_A = weights[f"{base_path}.lora_A"] - rank = lora_A.shape[1] - lora_layer = LoRALinear.from_linear(linear=original_layer, r=rank, scale=scale) + # Create and store LoRA layer + lora_layer = LoRALayers._create_lora_layer(weights, base_path, original_layer, scale) + lora_layers[base_path] = lora_layer - # Set the weights - lora_layer.lora_A = weights[f"{base_path}.lora_A"] - lora_layer.lora_B = weights[f"{base_path}.lora_B"] - - # Store the layer + @staticmethod + def _handle_top_level_component( + weights: dict, scale: float, transformer: nn.Module, lora_layers: dict, base_path: str, component_name: str + ): + original_layer = getattr(transformer, component_name) + lora_layer = LoRALayers._create_lora_layer(weights, base_path, original_layer, scale) lora_layers[base_path] = lora_layer @staticmethod @@ -210,7 +244,11 @@ class LoRALayers: @staticmethod def _set_attribute(block, key: str, val: dict, name: str): if block[key].get(name, False) and val.get(name, False): - block[key][name] = val[name] + if name == "to_out" and isinstance(block[key][name], list): + if len(block[key][name]) > 0: + block[key][name][0] = val[name] + else: + block[key][name] = val[name] @staticmethod def _get_nested_attr(obj, attr_path): diff --git a/src/mflux/flux/flux_initializer.py b/src/mflux/flux/flux_initializer.py index a0ec991..dd6e601 100644 --- a/src/mflux/flux/flux_initializer.py +++ b/src/mflux/flux/flux_initializer.py @@ -54,12 +54,13 @@ class FluxInitializer: weights = WeightHandler.load_regular_weights( repo_id=model_config.model_name, local_path=local_path, + transformer_repo_id=model_config.custom_transformer_model, ) # 3. Initialize all models flux_model.vae = VAE() - - # Use custom transformer if provided, otherwise create default + flux_model.t5_text_encoder = T5Encoder() + flux_model.clip_text_encoder = CLIPEncoder() if custom_transformer is not None: flux_model.transformer = custom_transformer else: @@ -69,9 +70,6 @@ class FluxInitializer: num_single_transformer_blocks=weights.num_single_transformer_blocks(), ) - flux_model.t5_text_encoder = T5Encoder() - flux_model.clip_text_encoder = CLIPEncoder() - # 4. Apply weights and quantize the models flux_model.bits = WeightUtil.set_weights_and_quantize( quantize_arg=quantize, diff --git a/src/mflux/flux_tools/fill/mask_util.py b/src/mflux/flux_tools/fill/mask_util.py index 835529c..37e747d 100644 --- a/src/mflux/flux_tools/fill/mask_util.py +++ b/src/mflux/flux_tools/fill/mask_util.py @@ -42,7 +42,7 @@ class MaskUtil: masked_image = ArrayUtil.pack_latents(latents=masked_image, height=height, width=width) # 4. Resize mask and pack latents - mask = MaskUtil._reshape_mask(the_mask=the_mask, height=height, width=width) + mask = MaskUtil.reshape_mask(the_mask=the_mask, height=height, width=width) mask = ArrayUtil.pack_latents(latents=mask, height=height, width=width, num_channels_latents=64) # 5. Concat the masked_image and the mask @@ -50,7 +50,7 @@ class MaskUtil: return masked_image_latents @staticmethod - def _reshape_mask(the_mask: mx.array, height: int, width: int) -> mx.array: + def reshape_mask(the_mask: mx.array, height: int, width: int) -> mx.array: mask = the_mask[:, 0, :, :] mask = mx.reshape(mask, (1, height // 8, 8, width // 8, 8)) mask = mx.transpose(mask, (0, 2, 4, 1, 3)) diff --git a/src/mflux/generate.py b/src/mflux/generate.py index 76744bc..ac75322 100644 --- a/src/mflux/generate.py +++ b/src/mflux/generate.py @@ -1,6 +1,7 @@ from mflux import Config, Flux1, ModelConfig, StopImageGenerationException from mflux.callbacks.callback_manager import CallbackManager from mflux.error.exceptions import PromptFileReadError +from mflux.ui import defaults as ui_defaults from mflux.ui.cli.parsers import CommandLineParser from mflux.ui.prompt_utils import get_effective_prompt @@ -16,6 +17,10 @@ def main(): parser.add_output_arguments() args = parser.parse_args() + # 0. Set default guidance value if not provided by user + if args.guidance is None: + args.guidance = ui_defaults.GUIDANCE_SCALE + # 1. Load the model flux = Flux1( model_config=ModelConfig.from_name(model_name=args.model, base_model=args.base_model), diff --git a/src/mflux/generate_controlnet.py b/src/mflux/generate_controlnet.py index 6a92e9e..778b1f6 100644 --- a/src/mflux/generate_controlnet.py +++ b/src/mflux/generate_controlnet.py @@ -1,6 +1,7 @@ from mflux import Config, Flux1Controlnet, ModelConfig, StopImageGenerationException from mflux.callbacks.callback_manager import CallbackManager from mflux.error.exceptions import PromptFileReadError +from mflux.ui import defaults as ui_defaults from mflux.ui.cli.parsers import CommandLineParser from mflux.ui.prompt_utils import get_effective_prompt @@ -16,6 +17,10 @@ def main(): parser.add_output_arguments() args = parser.parse_args() + # 0. Set default guidance value if not provided by user + if args.guidance is None: + args.guidance = ui_defaults.GUIDANCE_SCALE + # 1. Load the model flux = Flux1Controlnet( model_config=_get_controlnet_model_config(args.model), diff --git a/src/mflux/generate_depth.py b/src/mflux/generate_depth.py index a828af1..1a5d30a 100644 --- a/src/mflux/generate_depth.py +++ b/src/mflux/generate_depth.py @@ -2,6 +2,7 @@ from mflux import Config, StopImageGenerationException from mflux.callbacks.callback_manager import CallbackManager from mflux.error.exceptions import PromptFileReadError from mflux.flux_tools.depth.flux_depth import Flux1Depth +from mflux.ui import defaults as ui_defaults from mflux.ui.cli.parsers import CommandLineParser from mflux.ui.prompt_utils import get_effective_prompt @@ -19,7 +20,7 @@ def main(): # 0. Default to a medium guidance value for depth related tasks. if args.guidance is None: - args.guidance = 10 + args.guidance = ui_defaults.DEFAULT_DEPTH_GUIDANCE # 1. Load the model flux = Flux1Depth( diff --git a/src/mflux/generate_fill.py b/src/mflux/generate_fill.py index 85cfbde..7e34ae9 100644 --- a/src/mflux/generate_fill.py +++ b/src/mflux/generate_fill.py @@ -2,6 +2,7 @@ from mflux import Config, StopImageGenerationException from mflux.callbacks.callback_manager import CallbackManager from mflux.error.exceptions import PromptFileReadError from mflux.flux_tools.fill.flux_fill import Flux1Fill +from mflux.ui import defaults as ui_defaults from mflux.ui.cli.parsers import CommandLineParser from mflux.ui.prompt_utils import get_effective_prompt @@ -19,7 +20,7 @@ def main(): # 0. Default to a higher guidance value for fill related tasks. if args.guidance is None: - args.guidance = 30 + args.guidance = ui_defaults.DEFAULT_DEV_FILL_GUIDANCE # 1. Load the model flux = Flux1Fill( diff --git a/src/mflux/generate_in_context_catvton.py b/src/mflux/generate_in_context_catvton.py new file mode 100644 index 0000000..810e96b --- /dev/null +++ b/src/mflux/generate_in_context_catvton.py @@ -0,0 +1,80 @@ +from pathlib import Path + +from mflux import Config, ModelConfig, StopImageGenerationException +from mflux.callbacks.callback_manager import CallbackManager +from mflux.community.in_context.flux_in_context_fill import FluxInContextFill +from mflux.error.exceptions import PromptFileReadError +from mflux.ui import defaults as ui_defaults +from mflux.ui.cli.parsers import CommandLineParser +from mflux.ui.prompt_utils import get_effective_prompt + + +def main(): + # 0. Parse command line arguments + parser = CommandLineParser(description="Generate virtual try-on images using in-context learning.") + parser.add_general_arguments() + parser.add_model_arguments(require_model_arg=False) + parser.add_lora_arguments() + parser.add_image_generator_arguments(supports_metadata_config=False, require_prompt=False) + parser.add_catvton_arguments() + parser.add_in_context_arguments() + parser.add_output_arguments() + args = parser.parse_args() + + # 0. Default to a higher guidance value for fill + if args.guidance is None: + args.guidance = ui_defaults.DEFAULT_DEV_FILL_GUIDANCE + + # Set default CATVTON prompt if none provided + if not args.prompt and not args.prompt_file: + args.prompt = "The pair of images highlights a clothing and its styling on a model, high resolution, 4K, 8K; [IMAGE1] Detailed product shot of a clothing; [IMAGE2] The same cloth is worn by a model in a lifestyle setting." + + # Set sensible VAE tiling split for in-context generation (side-by-side images) + if args.vae_tiling: + args.vae_tiling_split = "vertical" + + # 1. Load the model + flux = FluxInContextFill( + model_config=ModelConfig.dev_fill_catvton(), + quantize=args.quantize, + local_path=args.path, + lora_paths=args.lora_paths, + lora_scales=args.lora_scales, + ) + + # 2. Register callbacks + memory_saver = CallbackManager.register_callbacks(args=args, flux=flux) + + try: + for seed in args.seed: + # 3. Generate an image for each seed value + image = flux.generate_image( + seed=seed, + prompt=get_effective_prompt(args), + left_image_path=args.garment_image, + right_image_path=args.person_image, + config=Config( + num_inference_steps=args.steps, + height=args.height, + width=args.width, + guidance=args.guidance, + image_path=args.person_image, + masked_image_path=args.person_mask, + ), + ) + + # 4. Save the image(s) + output_path = Path(args.output.format(seed=seed)) + image.get_right_half().save(path=output_path, export_json_metadata=args.metadata) + if args.save_full_image: + image.save(path=output_path.with_stem(output_path.stem + "_full")) + + except (StopImageGenerationException, PromptFileReadError) as exc: + print(exc) + finally: + if memory_saver: + print(memory_saver.memory_stats()) + + +if __name__ == "__main__": + main() diff --git a/src/mflux/generate_in_context.py b/src/mflux/generate_in_context_dev.py similarity index 79% rename from src/mflux/generate_in_context.py rename to src/mflux/generate_in_context_dev.py index dc518ef..9e1c778 100644 --- a/src/mflux/generate_in_context.py +++ b/src/mflux/generate_in_context_dev.py @@ -2,10 +2,11 @@ from pathlib import Path from mflux import Config, StopImageGenerationException from mflux.callbacks.callback_manager import CallbackManager -from mflux.community.in_context_lora.flux_in_context_lora import Flux1InContextLoRA -from mflux.community.in_context_lora.in_context_loras import LORA_REPO_ID, get_lora_filename +from mflux.community.in_context.flux_in_context_dev import Flux1InContextDev +from mflux.community.in_context.utils.in_context_loras import LORA_REPO_ID, get_lora_filename from mflux.config.model_config import ModelConfig from mflux.error.exceptions import PromptFileReadError +from mflux.ui import defaults as ui_defaults from mflux.ui.cli.parsers import CommandLineParser from mflux.ui.prompt_utils import get_effective_prompt @@ -18,17 +19,20 @@ def main(): parser.add_lora_arguments() parser.add_image_generator_arguments(supports_metadata_config=True) parser.add_image_to_image_arguments(required=True) + parser.add_in_context_arguments() parser.add_output_arguments() - parser.add_argument( - "--save-full-image", - action="store_true", - default=False, - help="Additionally, save the full image containing the reference image. Useful for verifying the in-context usage of the reference image.", - ) args = parser.parse_args() + # 0. Set default guidance value if not provided by user + if args.guidance is None: + args.guidance = ui_defaults.GUIDANCE_SCALE + + # Set sensible VAE tiling split for in-context generation (side-by-side images) + if args.vae_tiling: + args.vae_tiling_split = "vertical" + # 1. Load the model - flux = Flux1InContextLoRA( + flux = Flux1InContextDev( model_config=ModelConfig.dev(), quantize=args.quantize, lora_names=[get_lora_filename(args.lora_style)] if args.lora_style else None, @@ -59,6 +63,7 @@ def main(): image.get_right_half().save(path=output_path, export_json_metadata=args.metadata) if args.save_full_image: image.save(path=output_path.with_stem(output_path.stem + "_full")) + except (StopImageGenerationException, PromptFileReadError) as exc: print(exc) finally: diff --git a/src/mflux/generate_in_context_edit.py b/src/mflux/generate_in_context_edit.py new file mode 100644 index 0000000..a4d9525 --- /dev/null +++ b/src/mflux/generate_in_context_edit.py @@ -0,0 +1,103 @@ +from pathlib import Path + +from PIL import Image + +from mflux import Config, ModelConfig, StopImageGenerationException +from mflux.callbacks.callback_manager import CallbackManager +from mflux.community.in_context.flux_in_context_fill import FluxInContextFill +from mflux.community.in_context.utils.in_context_loras import prepare_ic_edit_loras +from mflux.error.exceptions import PromptFileReadError +from mflux.ui import defaults as ui_defaults +from mflux.ui.cli.parsers import CommandLineParser +from mflux.ui.prompt_utils import get_effective_prompt + + +def main(): + # 0. Parse command line arguments + parser = CommandLineParser(description="Generate images using in-context editing.") + parser.add_general_arguments() + parser.add_model_arguments(require_model_arg=False) + parser.add_lora_arguments() + parser.add_image_generator_arguments(supports_metadata_config=False, require_prompt=False) + parser.add_in_context_edit_arguments() + parser.add_in_context_arguments() + parser.add_output_arguments() + args = parser.parse_args() + + # 0. Default to a higher guidance value for fill related tasks. + if args.guidance is None: + args.guidance = ui_defaults.DEFAULT_DEV_FILL_GUIDANCE + + # Set sensible VAE tiling split for in-context generation (side-by-side images) + if args.vae_tiling: + args.vae_tiling_split = "vertical" + + # Auto-resize to optimal width for IC-Edit + width, height = _resize_for_ic_edit_optimal_width(args) + + # 1. Load the model with IC-Edit LoRA + flux = FluxInContextFill( + model_config=ModelConfig.dev_fill(), + quantize=args.quantize, + local_path=args.path, + lora_paths=prepare_ic_edit_loras(args.lora_paths), + lora_scales=args.lora_scales, + ) + + # 2. Register callbacks + memory_saver = CallbackManager.register_callbacks(args=args, flux=flux) + + try: + for seed in args.seed: + # 3. Generate an image for each seed value + image = flux.generate_image( + seed=seed, + prompt=_get_effective_ic_edit_prompt(args), + left_image_path=args.reference_image, + right_image_path=None, + config=Config( + num_inference_steps=args.steps, + height=height, + width=width, + guidance=args.guidance, + ), + ) + + # 4. Save the image(s) + output_path = Path(args.output.format(seed=seed)) + image.get_right_half().save(path=output_path, export_json_metadata=args.metadata) + if args.save_full_image: + image.save(path=output_path.with_stem(output_path.stem + "_full")) + + except (StopImageGenerationException, PromptFileReadError) as exc: + print(exc) + finally: + if memory_saver: + print(memory_saver.memory_stats()) + + +def _get_effective_ic_edit_prompt(args): + if hasattr(args, "instruction") and args.instruction: + return f"A diptych with two side-by-side images of the same scene. On the right, the scene is exactly the same as on the left but {args.instruction}" + else: + return get_effective_prompt(args) + + +def _resize_for_ic_edit_optimal_width(args): + with Image.open(args.reference_image) as img: + actual_width, actual_height = img.size + aspect_ratio = actual_height / actual_width + original_args_width = args.width + original_args_height = args.height + optimal_width = 512 + optimal_height = int(512 * aspect_ratio) + optimal_height = (optimal_height // 8) * 8 + print(f"[INFO] IC-Edit LoRA trained on 512px width. Auto-resizing from actual image {actual_width}x{actual_height} to {optimal_width}x{optimal_height}") # fmt:off + print(f"[INFO] Aspect ratio maintained: {aspect_ratio:.3f}") + if original_args_width != actual_width or original_args_height != actual_height: + print(f"[INFO] Note: Command line args specified {original_args_width}x{original_args_height}, but using actual image dimensions for scaling") # fmt:off + return optimal_width, optimal_height + + +if __name__ == "__main__": + main() diff --git a/src/mflux/generate_redux.py b/src/mflux/generate_redux.py index 6459b9e..86ce345 100644 --- a/src/mflux/generate_redux.py +++ b/src/mflux/generate_redux.py @@ -4,6 +4,7 @@ from mflux import Config, ModelConfig, StopImageGenerationException from mflux.callbacks.callback_manager import CallbackManager from mflux.error.exceptions import PromptFileReadError from mflux.flux_tools.redux.flux_redux import Flux1Redux +from mflux.ui import defaults as ui_defaults from mflux.ui.cli.parsers import CommandLineParser from mflux.ui.prompt_utils import get_effective_prompt @@ -19,6 +20,10 @@ def main(): parser.add_output_arguments() args = parser.parse_args() + # 0. Set default guidance value if not provided by user + if args.guidance is None: + args.guidance = ui_defaults.GUIDANCE_SCALE + # Validate and normalize redux image strengths redux_image_strengths = _validate_redux_image_strengths( redux_image_paths=args.redux_image_paths, diff --git a/src/mflux/ui/cli/parsers.py b/src/mflux/ui/cli/parsers.py index 2108999..4275a1f 100644 --- a/src/mflux/ui/cli/parsers.py +++ b/src/mflux/ui/cli/parsers.py @@ -5,7 +5,7 @@ import time import typing as t from pathlib import Path -from mflux.community.in_context_lora.in_context_loras import LORA_NAME_MAP, LORA_REPO_ID +from mflux.community.in_context.utils.in_context_loras import LORA_NAME_MAP, LORA_REPO_ID from mflux.ui import ( box_values, defaults as ui_defaults, @@ -72,10 +72,10 @@ class CommandLineParser(argparse.ArgumentParser): self.add_argument("--height", type=int, default=ui_defaults.HEIGHT, help=f"Image height (Default is {ui_defaults.HEIGHT})") self.add_argument("--width", type=int, default=ui_defaults.WIDTH, help=f"Image width (Default is {ui_defaults.HEIGHT})") self.add_argument("--steps", type=int, default=None, help="Inference Steps") - self.add_argument("--guidance", type=float, default=ui_defaults.GUIDANCE_SCALE, help=f"Guidance Scale (Default is {ui_defaults.GUIDANCE_SCALE})") + self.add_argument("--guidance", type=float, default=None, help=f"Guidance Scale (Default varies by tool: {ui_defaults.GUIDANCE_SCALE} for most, {ui_defaults.DEFAULT_DEV_FILL_GUIDANCE} for fill tools, {ui_defaults.DEFAULT_DEPTH_GUIDANCE} for depth)") - def add_image_generator_arguments(self, supports_metadata_config=False) -> None: - prompt_group = self.add_mutually_exclusive_group(required=(not supports_metadata_config)) + def add_image_generator_arguments(self, supports_metadata_config=False, require_prompt=True) -> None: + prompt_group = self.add_mutually_exclusive_group(required=(require_prompt and not supports_metadata_config)) prompt_group.add_argument("--prompt", type=str, help="The textual description of the image to generate.") prompt_group.add_argument("--prompt-file", type=Path, help="Path to a file containing the prompt text. The file will be re-read before each generation, allowing you to edit the prompt between iterations when using multiple seeds without restarting the program.") self.add_argument("--seed", type=int, default=None, nargs='+', help="Specify 1+ Entropy Seeds (Default is 1 time-based random-seed)") @@ -83,6 +83,7 @@ class CommandLineParser(argparse.ArgumentParser): self._add_image_generator_common_arguments() if supports_metadata_config: self.add_metadata_config() + self.require_prompt = require_prompt def add_image_to_image_arguments(self, required=False) -> None: self.supports_image_to_image = True @@ -98,6 +99,19 @@ class CommandLineParser(argparse.ArgumentParser): self.add_argument("--image-path", type=Path, required=True, help="Local path to the source image") self.add_argument("--masked-image-path", type=Path, required=True, help="Local path to the mask image") + def add_catvton_arguments(self) -> None: + self.add_argument("--person-image", type=str, required=True, help="Path to person image") + self.add_argument("--person-mask", type=str, required=True, help="Path to person mask image") + self.add_argument("--garment-image", type=str, required=True, help="Garment Image") + + def add_in_context_edit_arguments(self) -> None: + self.supports_in_context_edit = True + self.add_argument("--reference-image", type=str, required=True, help="Path to reference image") + self.add_argument("--instruction", type=str, help="User instruction to be wrapped in diptych template (e.g., 'make the hair black'). This will be automatically formatted as 'A diptych with two side-by-side images of the same scene. On the right, the scene is exactly the same as on the left but {instruction}'. Either --instruction or --prompt is required.") # fmt:off + + def add_in_context_arguments(self) -> None: + self.add_argument("--save-full-image", action="store_true", default=False, help="Additionally, save the full image containing the reference image. Useful for verifying the in-context usage of the reference image.") + def add_depth_arguments(self) -> None: self.add_argument("--image-path", type=Path, required=False, help="Local path to the source image") self.add_argument("--depth-image-path", type=Path, required=False, help="Local path to the depth image") @@ -242,11 +256,21 @@ class CommandLineParser(argparse.ArgumentParser): if self.supports_image_generation and namespace.prompt is None and namespace.prompt_file is None: # when metadata config is supported but neither prompt nor prompt-file is provided - self.error("Either --prompt or --prompt-file argument is required, or 'prompt' required in metadata config file") + # Only error if prompt is actually required + if getattr(self, 'require_prompt', True): + self.error("Either --prompt or --prompt-file argument is required, or 'prompt' required in metadata config file") if self.supports_image_generation and namespace.steps is None: namespace.steps = ui_defaults.MODEL_INFERENCE_STEPS.get(namespace.model, 14) + # In-context edit specific validations + if getattr(self, 'supports_in_context_edit', False): + if not getattr(namespace, 'prompt', None) and not getattr(namespace, 'instruction', None): + self.error("Either --prompt or --instruction argument is required for in-context editing") + + if getattr(namespace, 'prompt', None) and getattr(namespace, 'instruction', None): + self.error("Cannot use both --prompt and --instruction. Choose one.") + if self.supports_image_outpaint and namespace.image_outpaint_padding is not None: # parse and normalize any acceptable 1,2,3,4-tuple box value to 4-tuple namespace.image_outpaint_padding = box_values.parse_box_value(namespace.image_outpaint_padding) diff --git a/src/mflux/ui/defaults.py b/src/mflux/ui/defaults.py index 455a477..512a4db 100644 --- a/src/mflux/ui/defaults.py +++ b/src/mflux/ui/defaults.py @@ -1,5 +1,7 @@ BATTERY_PERCENTAGE_STOP_LIMIT = 5 CONTROLNET_STRENGTH = 0.4 +DEFAULT_DEV_FILL_GUIDANCE = 30 +DEFAULT_DEPTH_GUIDANCE = 10 GUIDANCE_SCALE = 3.5 HEIGHT, WIDTH = 1024, 1024 IMAGE_STRENGTH = 0.4 diff --git a/src/mflux/weights/weight_handler.py b/src/mflux/weights/weight_handler.py index 8e91430..b04cbe2 100644 --- a/src/mflux/weights/weight_handler.py +++ b/src/mflux/weights/weight_handler.py @@ -36,14 +36,22 @@ class WeightHandler: def load_regular_weights( repo_id: str | None = None, local_path: str | None = None, + transformer_repo_id: str | None = None, ) -> "WeightHandler": # Load the weights from disk, huggingface cache, or download from huggingface root_path = Path(local_path) if local_path else WeightHandler._download_or_get_cached_weights(repo_id) + # Some custom models might have a different specific transformer setup + if transformer_repo_id: + transformer_path = WeightHandler._download_transformer_weights(transformer_repo_id) + else: + transformer_path = root_path + + # Load the weights + transformer, quantization_level, mflux_version = WeightHandler.load_transformer(root_path=transformer_path) clip_encoder, _, _ = WeightHandler._load_clip_encoder(root_path=root_path) t5_encoder, _, _ = WeightHandler._load_t5_encoder(root_path=root_path) vae, _, _ = WeightHandler._load_vae(root_path=root_path) - transformer, quantization_level, mflux_version = WeightHandler.load_transformer(root_path=root_path) return WeightHandler( clip_encoder=clip_encoder, @@ -96,6 +104,17 @@ class WeightHandler: weights.pop("encoder") return weights, quantization_level, mflux_version + @staticmethod + def _safely_extract_ff_weights(ff_dict: dict) -> dict | None: + try: + net = ff_dict["net"] + return { + "linear1": net[0]["proj"], + "linear2": net[2], + } + except (KeyError, IndexError, TypeError): + return None + @staticmethod def load_transformer(root_path: Path | None = None, lora_path: str | None = None) -> tuple[dict, int, str | None]: weights, quantization_level, mflux_version = WeightHandler.get_weights("transformer", root_path, lora_path) @@ -112,16 +131,18 @@ class WeightHandler: # Reshape and process the huggingface weights if "transformer_blocks" in weights: for block in weights["transformer_blocks"]: - if block.get("ff") is not None: - block["ff"] = { - "linear1": block["ff"]["net"][0]["proj"], - "linear2": block["ff"]["net"][2], - } - if block.get("ff_context") is not None: - block["ff_context"] = { - "linear1": block["ff_context"]["net"][0]["proj"], - "linear2": block["ff_context"]["net"][2], - } + # Safely process ff weights + if "ff" in block: + extracted_ff = WeightHandler._safely_extract_ff_weights(block["ff"]) + if extracted_ff is not None: + block["ff"] = extracted_ff + + # Safely process ff_context weights + if "ff_context" in block: + extracted_ff_context = WeightHandler._safely_extract_ff_weights(block["ff_context"]) + if extracted_ff_context is not None: + block["ff_context"] = extracted_ff_context + return weights, quantization_level, mflux_version @staticmethod @@ -141,6 +162,17 @@ class WeightHandler: weights["encoder"]["conv_norm_out"] = {"norm": weights["encoder"]["conv_norm_out"]} return weights, quantization_level, mflux_version + @staticmethod + def _get_model_file_pattern(model_name: str, root_path: Path): + if model_name == "transformer": + nested_files = list(root_path.glob("transformer/*.safetensors")) + if nested_files: + return root_path.glob("transformer/*.safetensors") + else: + return root_path.glob("*.safetensors") + else: + return root_path.glob(model_name + "/*.safetensors") + @staticmethod def get_weights( model_name: str, @@ -152,7 +184,8 @@ class WeightHandler: mflux_version = None if root_path is not None: - for file in sorted(root_path.glob(model_name + "/*.safetensors")): + file_glob = WeightHandler._get_model_file_pattern(model_name, root_path) + for file in sorted(file_glob): data = mx.load(str(file), return_metadata=True) weight = list(data[0].items()) if len(data) > 1: @@ -190,3 +223,15 @@ class WeightHandler: ], ) ) + + @staticmethod + def _download_transformer_weights(repo_id: str) -> Path: + return Path( + snapshot_download( + repo_id=repo_id, + allow_patterns=[ + "transformer/*.safetensors", + "*.safetensors", + ], + ) + ) diff --git a/src/mflux/weights/weight_handler_lora.py b/src/mflux/weights/weight_handler_lora.py index 740873a..0c8f830 100644 --- a/src/mflux/weights/weight_handler_lora.py +++ b/src/mflux/weights/weight_handler_lora.py @@ -138,6 +138,12 @@ class WeightHandlerLoRA: def set_lora_layers(transformer_module: nn.Module, lora_layers: LoRALayers) -> None: transformer = lora_layers.layers.transformer + # Handle top-level transformer components (x_embedder, context_embedder, proj_out, etc.) + for attr_name in ["x_embedder", "context_embedder", "proj_out"]: + component = transformer.get(attr_name, None) + if component is not None: + setattr(transformer_module, attr_name, component) + # Handle transformer_blocks transformer_blocks = transformer.get("transformer_blocks", []) for i, weights in enumerate(transformer_blocks): diff --git a/src/mflux/weights/weight_handler_lora_huggingface.py b/src/mflux/weights/weight_handler_lora_huggingface.py index b5be70d..cbf641a 100644 --- a/src/mflux/weights/weight_handler_lora_huggingface.py +++ b/src/mflux/weights/weight_handler_lora_huggingface.py @@ -17,7 +17,7 @@ class WeightHandlerLoRAHuggingFace: lora_paths = [] if lora_names: for lora_name in lora_names: - lora_path = WeightHandlerLoRAHuggingFace._download_lora( + lora_path = WeightHandlerLoRAHuggingFace.download_lora( repo_id=repo_id, lora_name=lora_name, cache_dir=cache_dir, @@ -27,7 +27,7 @@ class WeightHandlerLoRAHuggingFace: return lora_paths @staticmethod - def _download_lora( + def download_lora( repo_id: str, lora_name: str, cache_dir: str | None = None, diff --git a/tests/arg_parser/test_cli_argparser.py b/tests/arg_parser/test_cli_argparser.py index 64e9df1..9a65a53 100644 --- a/tests/arg_parser/test_cli_argparser.py +++ b/tests/arg_parser/test_cli_argparser.py @@ -164,6 +164,56 @@ def mflux_concept_minimal_argv() -> list[str]: ] +@pytest.fixture +def mflux_catvton_parser() -> CommandLineParser: + parser = CommandLineParser(description="Generate virtual try-on images using in-context learning.") + parser.add_general_arguments() + parser.add_model_arguments(require_model_arg=False) + parser.add_lora_arguments() + parser.add_image_generator_arguments(supports_metadata_config=False, require_prompt=False) + parser.add_catvton_arguments() + parser.add_in_context_arguments() + parser.add_output_arguments() + return parser + + +@pytest.fixture +def mflux_catvton_minimal_argv() -> list[str]: + return [ + "mflux-generate-in-context-catvton", + "--person-image", + "person.png", + "--person-mask", + "person_mask.png", + "--garment-image", + "garment.png", + ] + + +@pytest.fixture +def mflux_in_context_edit_parser() -> CommandLineParser: + parser = CommandLineParser(description="Generate images using in-context editing.") + parser.add_general_arguments() + parser.add_model_arguments(require_model_arg=False) + parser.add_lora_arguments() + parser.add_image_generator_arguments(supports_metadata_config=False, require_prompt=False) + parser.add_in_context_edit_arguments() + parser.add_in_context_arguments() + parser.add_output_arguments() + return parser + + +@pytest.fixture +def mflux_in_context_edit_minimal_argv() -> list[str]: + return [ + "mflux-generate-in-context-edit", + "--reference-image", + "reference.png", + "--instruction", + "make the hair black", + ] + + def test_model_path_requires_model_arg(mflux_generate_parser): # when loading a model via --path, the model name still need to be specified with patch("sys.argv", "mflux-generate", "--path", "/some/saved/model"): @@ -613,18 +663,15 @@ def test_fill_default_guidance(): ): args = parser.parse_args() - # Verify initial guidance value is the UI default - assert args.guidance == ui_defaults.GUIDANCE_SCALE + # Verify initial guidance value is None (no default set by parser) + assert args.guidance is None # Simulate what happens in generate_fill.py if args.guidance is None: - args.guidance = 30 - else: - # In our test we'll just override it to simulate the behavior - args.guidance = 30 + args.guidance = ui_defaults.DEFAULT_DEV_FILL_GUIDANCE - # Now check that guidance is correctly set to 30 - assert args.guidance == 30 + # Now check that guidance is correctly set to the default dev fill guidance + assert args.guidance == ui_defaults.DEFAULT_DEV_FILL_GUIDANCE def test_save_depth_args(mflux_save_depth_parser, mflux_save_depth_minimal_argv): @@ -727,3 +774,102 @@ def test_concept_attention_args(mflux_concept_parser, mflux_concept_minimal_argv assert args.concept == "car" assert args.heatmap_layer_indices == [10, 11, 12] assert args.heatmap_timesteps == [0, 1, 2] + + +def test_catvton_args(mflux_catvton_parser, mflux_catvton_minimal_argv): + # Test required arguments + with patch("sys.argv", mflux_catvton_minimal_argv): + args = mflux_catvton_parser.parse_args() + assert args.person_image == "person.png" + assert args.person_mask == "person_mask.png" + assert args.garment_image == "garment.png" + + # Test prompt is None by default (set by the app, not parser) + assert args.prompt is None + + # Test missing required arguments + with patch("sys.argv", ["mflux-generate-in-context-catvton"]): + pytest.raises(SystemExit, mflux_catvton_parser.parse_args) + + with patch("sys.argv", ["mflux-generate-in-context-catvton", "--person-image", "person.png"]): + pytest.raises(SystemExit, mflux_catvton_parser.parse_args) + + with patch( + "sys.argv", ["mflux-generate-in-context-catvton", "--person-image", "person.png", "--person-mask", "mask.png"] + ): + pytest.raises(SystemExit, mflux_catvton_parser.parse_args) + + # Test custom prompt can be set + with patch("sys.argv", mflux_catvton_minimal_argv + ["--prompt", "custom prompt"]): + args = mflux_catvton_parser.parse_args() + assert args.prompt == "custom prompt" + + # Test VAE tiling split argument + with patch("sys.argv", mflux_catvton_minimal_argv + ["--vae-tiling"]): + args = mflux_catvton_parser.parse_args() + assert args.vae_tiling is True + assert args.vae_tiling_split == "horizontal" # Default value from parser + + +def test_in_context_edit_args(mflux_in_context_edit_parser, mflux_in_context_edit_minimal_argv): + # Test required arguments with instruction + with patch("sys.argv", mflux_in_context_edit_minimal_argv): + args = mflux_in_context_edit_parser.parse_args() + assert args.reference_image == "reference.png" + assert args.instruction == "make the hair black" + assert hasattr(mflux_in_context_edit_parser, "supports_in_context_edit") + assert mflux_in_context_edit_parser.supports_in_context_edit is True + + # Test with prompt instead of instruction + with patch( + "sys.argv", + [ + "mflux-generate-in-context-edit", + "--reference-image", + "reference.png", + "--prompt", + "A diptych with custom prompt", + ], + ): + args = mflux_in_context_edit_parser.parse_args() + assert args.reference_image == "reference.png" + assert args.prompt == "A diptych with custom prompt" + + # Test missing required arguments + with patch("sys.argv", ["mflux-generate-in-context-edit"]): + pytest.raises(SystemExit, mflux_in_context_edit_parser.parse_args) + + with patch("sys.argv", ["mflux-generate-in-context-edit", "--reference-image", "reference.png"]): + pytest.raises(SystemExit, mflux_in_context_edit_parser.parse_args) + + # Test both prompt and instruction provided (should error) + with patch( + "sys.argv", + [ + "mflux-generate-in-context-edit", + "--reference-image", + "reference.png", + "--prompt", + "test prompt", + "--instruction", + "test instruction", + ], + ): + pytest.raises(SystemExit, mflux_in_context_edit_parser.parse_args) + + # Test VAE tiling split argument + with patch("sys.argv", mflux_in_context_edit_minimal_argv + ["--vae-tiling"]): + args = mflux_in_context_edit_parser.parse_args() + assert args.vae_tiling is True + assert args.vae_tiling_split == "horizontal" # Default value from parser + + +def test_in_context_args(mflux_catvton_parser, mflux_catvton_minimal_argv): + # Test save_full_image flag + with patch("sys.argv", mflux_catvton_minimal_argv): + args = mflux_catvton_parser.parse_args() + assert args.save_full_image is False + + with patch("sys.argv", mflux_catvton_minimal_argv + ["--save-full-image"]): + args = mflux_catvton_parser.parse_args() + assert args.save_full_image is True diff --git a/tests/image_generation/helpers/image_generation_fill_test_helper.py b/tests/image_generation/helpers/image_generation_fill_test_helper.py index ced31f7..09d6ea3 100644 --- a/tests/image_generation/helpers/image_generation_fill_test_helper.py +++ b/tests/image_generation/helpers/image_generation_fill_test_helper.py @@ -5,6 +5,7 @@ from PIL import Image from mflux import Config, ModelConfig from mflux.flux_tools.fill.flux_fill import Flux1Fill +from mflux.ui import defaults as ui_defaults from tests.image_generation.helpers.image_generation_test_helper import ImageGeneratorTestHelper @@ -49,7 +50,7 @@ class ImageGeneratorFillTestHelper: width=width, image_path=image_path, masked_image_path=masked_image_path, - guidance=30, + guidance=ui_defaults.DEFAULT_DEV_FILL_GUIDANCE, ), ) image.save(path=output_image_path, overwrite=True) diff --git a/tests/image_generation/helpers/image_generation_ic_edit_test_helper.py b/tests/image_generation/helpers/image_generation_ic_edit_test_helper.py new file mode 100644 index 0000000..00bcea4 --- /dev/null +++ b/tests/image_generation/helpers/image_generation_ic_edit_test_helper.py @@ -0,0 +1,73 @@ +import os +from pathlib import Path + +import numpy as np +from PIL import Image + +from mflux import Config, ModelConfig +from mflux.community.in_context.flux_in_context_fill import FluxInContextFill +from mflux.community.in_context.utils.in_context_loras import prepare_ic_edit_loras + + +class ImageGeneratorICEditTestHelper: + @staticmethod + def assert_matches_reference_image( + reference_image_path: str, + output_image_path: str, + prompt: str, + steps: int, + seed: int, + height: int | None = None, + width: int | None = None, + reference_image: str | None = None, + lora_paths: list[str] | None = None, + lora_scales: list[float] | None = None, + ): + # resolve paths + reference_image_path = ImageGeneratorICEditTestHelper.resolve_path(reference_image_path) + output_image_path = ImageGeneratorICEditTestHelper.resolve_path(output_image_path) + reference_image = ImageGeneratorICEditTestHelper.resolve_path(reference_image) + lora_paths = [str(ImageGeneratorICEditTestHelper.resolve_path(p)) for p in lora_paths] if lora_paths else None + + try: + # given + flux = FluxInContextFill( + model_config=ModelConfig.dev_fill(), + quantize=8, + lora_paths=prepare_ic_edit_loras(lora_paths), + lora_scales=lora_scales, + ) + + # when + image = flux.generate_image( + seed=seed, + prompt=prompt, + left_image_path=str(reference_image), + right_image_path=None, + config=Config( + num_inference_steps=steps, + height=height, + width=width, + ), + ) + + # Save the result + image.get_right_half().save(path=output_image_path, overwrite=True) + + # then + np.testing.assert_array_equal( + np.array(Image.open(output_image_path)), + np.array(Image.open(reference_image_path)), + err_msg=f"Generated image doesn't match reference image. Check {output_image_path} vs {reference_image_path}", + ) + + finally: + # cleanup + if os.path.exists(output_image_path): + os.remove(output_image_path) + + @staticmethod + def resolve_path(path) -> Path | None: + if path is None: + return None + return Path(__file__).parent.parent.parent / "resources" / path diff --git a/tests/image_generation/helpers/image_generation_in_context_test_helper.py b/tests/image_generation/helpers/image_generation_in_context_test_helper.py index 17bd3e9..7c99c78 100644 --- a/tests/image_generation/helpers/image_generation_in_context_test_helper.py +++ b/tests/image_generation/helpers/image_generation_in_context_test_helper.py @@ -5,8 +5,8 @@ import numpy as np from PIL import Image from mflux import Config, ModelConfig -from mflux.community.in_context_lora.flux_in_context_lora import Flux1InContextLoRA -from mflux.community.in_context_lora.in_context_loras import LORA_REPO_ID, get_lora_filename +from mflux.community.in_context.flux_in_context_dev import Flux1InContextDev +from mflux.community.in_context.utils.in_context_loras import LORA_REPO_ID, get_lora_filename class ImageGeneratorInContextTestHelper: @@ -35,7 +35,7 @@ class ImageGeneratorInContextTestHelper: try: # given - flux = Flux1InContextLoRA( + flux = Flux1InContextDev( model_config=model_config, quantize=8, lora_names=[get_lora_filename(lora_style)] if lora_style else None, diff --git a/tests/image_generation/test_generate_image_in_context.py b/tests/image_generation/test_generate_image_in_context.py index 584b451..0bccd81 100644 --- a/tests/image_generation/test_generate_image_in_context.py +++ b/tests/image_generation/test_generate_image_in_context.py @@ -1,4 +1,5 @@ from mflux import ModelConfig +from tests.image_generation.helpers.image_generation_ic_edit_test_helper import ImageGeneratorICEditTestHelper from tests.image_generation.helpers.image_generation_in_context_test_helper import ImageGeneratorInContextTestHelper @@ -16,3 +17,15 @@ class TestImageGeneratorInContext: image_path="ic_lora_reference_logo.png", lora_style="identity", ) + + def test_ic_edit_with_instruction(self): + ImageGeneratorICEditTestHelper.assert_matches_reference_image( + reference_image_path="ic_edit_reference.png", + output_image_path="output_ic_edit.png", + steps=20, + seed=2799665, + height=224, + width=512, + prompt="A diptych with two side-by-side images of the same scene. On the right, the scene is exactly the same as on the left but remove the cheese", + reference_image="reference_redux_dev.png", + ) diff --git a/tests/resources/ic_edit_reference.png b/tests/resources/ic_edit_reference.png new file mode 100644 index 0000000000000000000000000000000000000000..a483b6dfaef8162c2bd1f95fe23064e5827fc0b7 GIT binary patch literal 171693 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