Skip to content

Commit 355421d

Browse files
authored
Merge pull request #113 from cubist38/feat/mflux
Feat/mflux
2 parents a7ee056 + 99812bf commit 355421d

File tree

6 files changed

+240
-132
lines changed

6 files changed

+240
-132
lines changed

README.md

Lines changed: 83 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ This repository hosts a high-performance API server that provides OpenAI-compati
4040
- 📈 **Performance and queue monitoring endpoints**
4141
- 🧑‍💻 **Easy Python and CLI usage**
4242
- 🛡️ **Robust error handling and request management**
43-
- 🎛️ **LoRA adapter support** for fine-tuned image generation
43+
- 🎛️ **LoRA adapter support** for fine-tuned image generation and editing
4444
-**Configurable quantization** (4-bit, 8-bit, 16-bit) for optimal performance
4545
- 🧠 **Customizable context length** for memory optimization and performance tuning
4646

@@ -97,8 +97,8 @@ The server supports six types of MLX models:
9797

9898
1. **Text-only models** (`--model-type lm`) - Uses the `mlx-lm` library for pure language models
9999
2. **Multimodal models** (`--model-type multimodal`) - Uses the `mlx-vlm` library for multimodal models that can process text, images, and audio
100-
3. **Image generation models** (`--model-type image-generation`) - Uses the `mflux` library for Flux-series image generation models with enhanced configurations ⚠️ *Requires manual installation of `mflux`*
101-
4. **Image editing models** (`--model-type image-edit`) - Uses the `mflux` library for Flux-series image editing models ⚠️ *Requires manual installation of `mflux`*
100+
3. **Image generation models** (`--model-type image-generation`) - Uses the `mflux` library for Flux-series image generation models with enhanced configurations
101+
4. **Image editing models** (`--model-type image-edit`) - Uses the `mflux` library for Flux-series image editing models
102102
5. **Embeddings models** (`--model-type embeddings`) - Uses the `mlx-embeddings` library for text embeddings generation with optimized memory management
103103
6. **Whisper models** (`--model-type whisper`) - Uses the `mlx-whisper` library for audio transcription and speech recognition ⚠️ *Requires ffmpeg installation*
104104

@@ -108,21 +108,21 @@ The server supports six types of MLX models:
108108
109109
### Flux-Series Image Models
110110

111-
> **⚠️ Note:** Image generation and editing capabilities require manual installation of `mflux`: `pip install git+https://github.com/cubist38/mflux.git`
112-
113-
The server supports multiple Flux model configurations for advanced image generation and editing:
111+
The server supports multiple Flux and Qwen model configurations for advanced image generation and editing:
114112

115113
#### Image Generation Models
116114
- **`flux-schnell`** - Fast generation with 4 default steps, no guidance (best for quick iterations)
117115
- **`flux-dev`** - High-quality generation with 25 default steps, 3.5 guidance (balanced quality/speed)
118116
- **`flux-krea-dev`** - Premium quality with 28 default steps, 4.5 guidance (highest quality)
117+
- **`qwen-image`** - Qwen image generation model with 50 default steps, 4.0 guidance (high-quality Qwen-based generation)
119118

120119
#### Image Editing Models
121120
- **`flux-kontext-dev`** - Context-aware editing with 28 default steps, 2.5 guidance (specialized for contextual image editing)
121+
- **`qwen-image-edit`** - Qwen image editing model with 50 default steps, 4.0 guidance (high-quality Qwen-based editing)
122122

123123
Each configuration supports:
124124
- **Quantization levels**: 4-bit, 8-bit, or 16-bit for memory/performance optimization
125-
- **LoRA adapters**: Multiple LoRA paths with custom scaling for fine-tuned generation.
125+
- **LoRA adapters**: Multiple LoRA paths with custom scaling for fine-tuned generation and editing (supported for all Flux and Qwen image models).
126126
- **Custom parameters**: Steps, guidance, negative prompts, and more
127127

128128
### Context Length Configuration
@@ -200,9 +200,6 @@ Follow these steps to set up the MLX-powered server:
200200
git clone https://github.com/cubist38/mlx-openai-server.git
201201
cd mlx-openai-server
202202
pip install -e .
203-
204-
# Optional: For image generation/editing support, also install mflux
205-
pip install git+https://github.com/cubist38/mflux.git
206203
```
207204

208205
### Using Conda (Recommended)
@@ -237,9 +234,6 @@ For better environment management and to avoid architecture issues, we recommend
237234
git clone https://github.com/cubist38/mlx-openai-server.git
238235
cd mlx-openai-server
239236
pip install -e .
240-
241-
# Optional: For image generation/editing support, also install mflux
242-
pip install git+https://github.com/cubist38/mflux.git
243237
```
244238

245239
### Optional Dependencies
@@ -257,23 +251,14 @@ pip install mlx-openai-server
257251
- All core API endpoints and functionality
258252

259253
#### Image Generation & Editing Support
260-
For image generation and editing capabilities, you need to install `mflux` manually:
254+
The server includes support for image generation and editing capabilities:
261255

262-
```bash
263-
# First install the base server
264-
pip install mlx-openai-server
265-
266-
# Then install mflux for image generation/editing support
267-
pip install git+https://github.com/cubist38/mflux.git
268-
```
269-
270-
**Additional features with mflux:**
256+
**Additional features:**
271257
- Image generation models (`--model-type image-generation`)
272258
- Image editing models (`--model-type image-edit`)
273259
- MLX Flux-series model support
274-
- LoRA adapter support for fine-tuned generation
275-
276-
> **Note:** If you try to use image generation or editing without `mflux` installed, you'll receive a clear error message directing you to install it manually.
260+
- Qwen Image model support
261+
- LoRA adapter support for fine-tuned generation and editing
277262

278263
#### Whisper Models Support
279264
For whisper models to work properly, you need to install ffmpeg:
@@ -315,21 +300,21 @@ python -m app.main \
315300
--queue-timeout 300 \
316301
--queue-size 100
317302
318-
# For image generation models (Flux-series)
303+
# For image generation models (Flux-series or Qwen)
319304
python -m app.main \
320305
--model-type image-generation \
321-
--model-path <path-to-local-flux-model> \
322-
--config-name <flux-schnell|flux-dev|flux-krea-dev> \
306+
--model-path <path-to-local-model> \
307+
--config-name <flux-schnell|flux-dev|flux-krea-dev|qwen-image> \
323308
--quantize <4|8|16> \
324309
--max-concurrency 1 \
325310
--queue-timeout 300 \
326311
--queue-size 100
327312
328-
# For image editing models (Flux-series)
313+
# For image editing models (Flux-series or Qwen)
329314
python -m app.main \
330315
--model-type image-edit \
331-
--model-path <path-to-local-flux-model> \
332-
--config-name flux-kontext-dev \
316+
--model-path <path-to-local-model> \
317+
--config-name <flux-kontext-dev|qwen-image-edit> \
333318
--quantize <4|8|16> \
334319
--max-concurrency 1 \
335320
--queue-timeout 300 \
@@ -373,19 +358,19 @@ mlx-openai-server launch \
373358
--model-type <lm|multimodal> \
374359
375360
376-
# For image generation models (Flux-series)
361+
# For image generation models (Flux-series or Qwen)
377362
mlx-openai-server launch \
378363
--model-type image-generation \
379-
--model-path <path-to-local-flux-model> \
380-
--config-name <flux-schnell|flux-dev|flux-krea-dev> \
364+
--model-path <path-to-local-model> \
365+
--config-name <flux-schnell|flux-dev|flux-krea-dev|qwen-image> \
381366
--quantize 8 \
382367
383368
384-
# For image editing models (Flux-series)
369+
# For image editing models (Flux-series or Qwen)
385370
mlx-openai-server launch \
386371
--model-type image-edit \
387-
--model-path <path-to-local-flux-model> \
388-
--config-name flux-kontext-dev \
372+
--model-path <path-to-local-model> \
373+
--config-name <flux-kontext-dev|qwen-image-edit> \
389374
--quantize 8 \
390375
391376
@@ -419,9 +404,9 @@ mlx-openai-server launch \
419404
- `whisper` for whisper models (audio transcription)
420405
- Default: `lm`
421406
- `--context-length`: Context length for language models. Controls the maximum sequence length for text processing and memory usage optimization. Default: `None` (uses model's default context length).
422-
- `--config-name`: Flux model configuration to use. Only used for `image-generation` and `image-edit` model types:
423-
- For `image-generation`: `flux-schnell`, `flux-dev`, `flux-krea-dev`
424-
- For `image-edit`: `flux-kontext-dev`
407+
- `--config-name`: Model configuration to use. Only used for `image-generation` and `image-edit` model types:
408+
- For `image-generation`: `flux-schnell`, `flux-dev`, `flux-krea-dev`, `qwen-image`
409+
- For `image-edit`: `flux-kontext-dev`, `qwen-image-edit`
425410
- Default: `flux-schnell` for image-generation, `flux-kontext-dev` for image-edit
426411
- `--quantize`: Quantization level for Flux models. Available options: `4`, `8`, `16`. Default: `8`
427412
- `--lora-paths`: Comma-separated paths to LoRA adapter files.
@@ -594,6 +579,18 @@ python -m app.main \
594579
--queue-size 100
595580
```
596581

582+
*High-quality generation with Qwen Image:*
583+
```bash
584+
python -m app.main \
585+
--model-type image-generation \
586+
--model-path <path-to-local-qwen-model> \
587+
--config-name qwen-image \
588+
--quantize 8 \
589+
--max-concurrency 1 \
590+
--queue-timeout 300 \
591+
--queue-size 100
592+
```
593+
597594
*Image editing with Kontext:*
598595
```bash
599596
python -m app.main \
@@ -606,7 +603,19 @@ python -m app.main \
606603
--queue-size 100
607604
```
608605

609-
*With LoRA adapters (image generation only):*
606+
*Image editing with Qwen Image Edit:*
607+
```bash
608+
python -m app.main \
609+
--model-type image-edit \
610+
--model-path <path-to-local-qwen-model> \
611+
--config-name qwen-image-edit \
612+
--quantize 8 \
613+
--max-concurrency 1 \
614+
--queue-timeout 300 \
615+
--queue-size 100
616+
```
617+
618+
*With LoRA adapters (image generation):*
610619
```bash
611620
python -m app.main \
612621
--model-type image-generation \
@@ -620,6 +629,20 @@ python -m app.main \
620629
--queue-size 100
621630
```
622631

632+
*With LoRA adapters (image editing):*
633+
```bash
634+
python -m app.main \
635+
--model-type image-edit \
636+
--model-path <path-to-local-flux-model> \
637+
--config-name flux-kontext-dev \
638+
--quantize 8 \
639+
--lora-paths "/path/to/lora1.safetensors,/path/to/lora2.safetensors" \
640+
--lora-scales "0.8,0.6" \
641+
--max-concurrency 1 \
642+
--queue-timeout 300 \
643+
--queue-size 100
644+
```
645+
623646
**Whisper models:**
624647

625648
*Audio transcription with Whisper:*
@@ -648,18 +671,21 @@ mlx-openai-server launch --help
648671
# For text-only or multimodal models
649672
mlx-openai-server launch --model-path <path-to-mlx-model> --model-type <lm|multimodal> --context-length 8192
650673
651-
# For image generation models (Flux-series)
652-
mlx-openai-server launch --model-type image-generation --model-path <path-to-local-flux-model> --config-name <flux-schnell|flux-dev|flux-krea-dev>
674+
# For image generation models (Flux-series or Qwen)
675+
mlx-openai-server launch --model-type image-generation --model-path <path-to-local-model> --config-name <flux-schnell|flux-dev|flux-krea-dev|qwen-image>
653676
654-
# For image editing models (Flux-series)
655-
mlx-openai-server launch --model-type image-edit --model-path <path-to-local-flux-model> --config-name flux-kontext-dev
677+
# For image editing models (Flux-series or Qwen)
678+
mlx-openai-server launch --model-type image-edit --model-path <path-to-local-model> --config-name <flux-kontext-dev|qwen-image-edit>
656679
657680
# For whisper models
658681
mlx-openai-server launch --model-path mlx-community/whisper-large-v3-mlx --model-type whisper
659682
660-
# With LoRA adapters (image generation only)
683+
# With LoRA adapters (image generation)
661684
mlx-openai-server launch --model-type image-generation --model-path <path-to-local-flux-model> --config-name flux-dev --lora-paths "/path/to/lora1.safetensors,/path/to/lora2.safetensors" --lora-scales "0.8,0.6"
662685
686+
# With LoRA adapters (image editing)
687+
mlx-openai-server launch --model-type image-edit --model-path <path-to-local-flux-model> --config-name flux-kontext-dev --lora-paths "/path/to/lora1.safetensors,/path/to/lora2.safetensors" --lora-scales "0.8,0.6"
688+
663689
# With custom logging configuration
664690
mlx-openai-server launch --model-path <path-to-mlx-model> --model-type lm --log-file /tmp/server.log --log-level DEBUG
665691
@@ -846,8 +872,6 @@ print(response.choices[0].message.content)
846872

847873
#### Advanced Image Generation with Flux-Series Models
848874

849-
> **⚠️ Note:** Image generation requires manual installation of `mflux`: `pip install git+https://github.com/cubist38/mflux.git`
850-
851875
```python
852876
import openai
853877
import base64
@@ -907,17 +931,15 @@ if response.status_code == 200:
907931
- `model`: Model identifier (defaults to "local-image-generation-model")
908932
- `size`: Image dimensions - "256x256", "512x512", or "1024x1024" (default: "1024x1024")
909933
- `negative_prompt`: What to avoid in the generated image (optional)
910-
- `steps`: Number of inference steps, 1-50 (default varies by config: 4 for Schnell, 25 for Dev, 28 for Krea-Dev)
934+
- `steps`: Number of inference steps, 1-50 (default varies by config: 4 for Schnell, 25 for Dev, 28 for Krea-Dev, 50 for Qwen Image)
911935
- `seed`: Random seed for reproducible generation (optional)
912936
- `priority`: Task priority - "low", "normal", "high" (default: "normal")
913937
- `async_mode`: Whether to process asynchronously (default: false)
914938

915-
> **Note:** Image generation requires running the server with `--model-type image-generation` and manual installation of `mflux`: `pip install git+https://github.com/cubist38/mflux.git`. The server uses MLX Flux-series models for high-quality image generation with configurable quality/speed trade-offs.
939+
> **Note:** Image generation requires running the server with `--model-type image-generation`. The server supports MLX Flux-series models (flux-schnell, flux-dev, flux-krea-dev) and Qwen Image models (qwen-image) for high-quality image generation with configurable quality/speed trade-offs.
916940
917941
#### Image Editing with Flux-Series Models
918942

919-
> **⚠️ Note:** Image editing requires manual installation of `mflux`: `pip install git+https://github.com/cubist38/mflux.git`
920-
921943
```python
922944
import openai
923945
import base64
@@ -981,13 +1003,13 @@ if response.status_code == 200:
9811003
- `prompt`: Text description of the desired edit (required, max 1000 characters)
9821004
- `model`: Model identifier (defaults to "flux-kontext-dev")
9831005
- `negative_prompt`: What to avoid in the edited image (optional)
984-
- `guidance_scale`: Controls how closely the model follows the prompt (default: 2.5)
985-
- `steps`: Number of inference steps, 1-50 (default: 4)
1006+
- `guidance_scale`: Controls how closely the model follows the prompt (default: 2.5 for flux-kontext-dev, 4.0 for qwen-image-edit)
1007+
- `steps`: Number of inference steps, 1-50 (default: 4 for flux-kontext-dev, 50 for qwen-image-edit)
9861008
- `seed`: Random seed for reproducible editing (default: 42)
9871009
- `size`: Output image dimensions - "256x256", "512x512", or "1024x1024" (optional)
9881010
- `response_format`: Response format - "b64_json" (default: "b64_json")
9891011

990-
> **Note:** Image editing requires running the server with `--model-type image-edit` and manual installation of `mflux`: `pip install git+https://github.com/cubist38/mflux.git`. The server uses MLX Flux-series models for high-quality image editing with configurable quality/speed trade-offs.
1012+
> **Note:** Image editing requires running the server with `--model-type image-edit`. The server supports MLX Flux-series models (flux-kontext-dev) and Qwen Image Edit models (qwen-image-edit) for high-quality image editing with configurable quality/speed trade-offs.
9911013
9921014
#### Function Calling
9931015
```python
@@ -1474,23 +1496,22 @@ The repository includes example notebooks to help you get started with different
14741496
- Exploring different types of audio analysis prompts
14751497
- Understanding audio transcription and content analysis capabilities
14761498

1477-
- **image_generations.ipynb**: A comprehensive guide to image generation using MLX Flux-series models, including:
1499+
- **image_generations.ipynb**: A comprehensive guide to image generation using MLX Flux-series and Qwen Image models, including:
14781500
- Setting up connection to MLX Server for image generation
14791501
- Basic image generation with default parameters
14801502
- Advanced image generation with custom parameters (negative prompts, steps, seed)
1481-
- Working with different Flux configurations (schnell, dev, Krea-dev)
1503+
- Working with different Flux configurations (schnell, dev, Krea-dev) and Qwen Image models
14821504
- Using LoRA adapters for fine-tuned generation
14831505
- Optimizing performance with quantization settings
1484-
> **⚠️ Note:** Requires manual installation of `mflux`: `pip install git+https://github.com/cubist38/mflux.git`
14851506

1486-
- **image_edit.ipynb**: A comprehensive guide to image editing using MLX Flux-series models, including:
1507+
- **image_edit.ipynb**: A comprehensive guide to image editing using MLX Flux-series and Qwen Image Edit models, including:
14871508
- Setting up connection to MLX Server for image editing
14881509
- Basic image editing with default parameters
14891510
- Advanced image editing with custom parameters (guidance scale, steps, seed)
1490-
- Working with the flux-kontext-dev configuration for contextual editing
1511+
- Working with the flux-kontext-dev and qwen-image-edit configurations for contextual editing
1512+
- Using LoRA adapters for fine-tuned editing
14911513
- Understanding the differences between generation and editing workflows
14921514
- Best practices for effective image editing prompts
1493-
> **⚠️ Note:** Requires manual installation of `mflux`: `pip install git+https://github.com/cubist38/mflux.git`
14941515

14951516
## Community & Support
14961517

app/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ def cli():
120120
@click.option(
121121
"--config-name",
122122
default=None,
123-
type=click.Choice(["flux-schnell", "flux-dev", "flux-krea-dev", "flux-kontext-dev"]),
124-
help="Config name of the model. Only used for image-generation and image-edit Flux models.",
123+
type=click.Choice(["flux-schnell", "flux-dev", "flux-krea-dev", "flux-kontext-dev", "qwen-image", "qwen-image-edit"]),
124+
help="Config name of the model. Only used for image-generation and image-edit models.",
125125
)
126126
@click.option(
127127
"--lora-paths",

app/handler/mflux.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212

1313
from PIL import Image
1414
from loguru import logger
15-
from fastapi import HTTPException, UploadFile
15+
from fastapi import HTTPException
1616
from ..core.queue import RequestQueue
17-
from ..models.mflux import FluxModel
17+
from ..models.mflux import ImageGenerationModel
1818
from ..utils.errors import create_error_response
1919
from ..schemas.openai import ImageSize, ImageGenerationRequest, ImageGenerationResponse, ImageEditRequest, ImageEditResponse, ImageData
2020

@@ -45,7 +45,7 @@ def __init__(self, model_path: str, max_concurrency: int = 1, quantize: int = 8,
4545
self.lora_paths = lora_paths
4646
self.lora_scales = lora_scales
4747

48-
self.model = FluxModel(
48+
self.model = ImageGenerationModel(
4949
model_path=model_path,
5050
quantize=quantize,
5151
config_name=config_name,
@@ -334,7 +334,7 @@ async def _process_request(self, request_data: Dict[str, Any]) -> Image.Image:
334334
width = request_data.get("width", 1024)
335335
height = request_data.get("height", 1024)
336336
image_path = request_data.get("image_path") # For image editing
337-
guidance = request_data.get("guidance_scale", 2.5)
337+
guidance = request_data.get("guidance", 2.5)
338338

339339
# Prepare model parameters
340340
model_params = {
@@ -433,3 +433,7 @@ def __del__(self):
433433
return
434434
# Set flag to prevent multiple cleanup attempts
435435
self._cleaned = True
436+
437+
if __name__ == "__main__":
438+
handler = MLXFluxHandler(model_path="qwen-image", config_name="qwen-image")
439+
print(handler.model.get_model_info("qwen-image"))

0 commit comments

Comments
 (0)