diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.idea/.gitignore b/.idea/.gitignore old mode 100644 new mode 100755 diff --git a/.idea/flux2.iml b/.idea/flux2.iml old mode 100644 new mode 100755 diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml old mode 100644 new mode 100755 diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml old mode 100644 new mode 100755 diff --git a/.idea/misc.xml b/.idea/misc.xml old mode 100644 new mode 100755 diff --git a/.idea/modules.xml b/.idea/modules.xml old mode 100644 new mode 100755 diff --git a/.idea/vcs.xml b/.idea/vcs.xml old mode 100644 new mode 100755 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml old mode 100644 new mode 100755 diff --git a/.yamlfmt.yaml b/.yamlfmt.yaml old mode 100644 new mode 100755 diff --git a/Dockerfile b/Dockerfile new file mode 100755 index 0000000..024e2d3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,37 @@ +FROM ghcr.io/astral-sh/uv:latest AS uv_bin +FROM nvidia/cuda:12.4.1-base-ubuntu22.04 + +# 1. 基础环境配置 +ENV UV_LINK_MODE=copy \ + UV_COMPILE_BYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + UV_PROJECT_ENVIRONMENT=/app/.venv + +COPY --from=uv_bin /uv /uvx /bin/ + +RUN apt-get update && apt-get install -y --no-install-recommends \ + wget \ + libcurl4-openssl-dev \ + build-essential \ + libgl1 \ + libglib2.0-0 \ + ca-certificates \ + git \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY pyproject.toml uv.lock ./ + +ENV UV_COMPILE_BYTECODE=0 + +RUN uv sync --frozen --no-dev --no-install-project --python 3.12 + +# 4. 拷贝项目文件并安装项目本身 +RUN uv sync --frozen --no-dev --python 3.12 + +ENV PATH="/app/.venv/bin:$PATH" + +EXPOSE 8000 +CMD ["uv", "run","-m","app.litserve_serve"] diff --git a/LICENSE.md b/LICENSE.md old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/litserve/app.py b/app/litserve/app.py old mode 100644 new mode 100755 similarity index 100% rename from litserve/app.py rename to app/litserve/app.py diff --git a/litserve/cli.py b/app/litserve/cli.py old mode 100644 new mode 100755 similarity index 100% rename from litserve/cli.py rename to app/litserve/cli.py diff --git a/litserve/client.py b/app/litserve/client.py old mode 100644 new mode 100755 similarity index 100% rename from litserve/client.py rename to app/litserve/client.py diff --git a/litserve/model.py b/app/litserve/model.py old mode 100644 new mode 100755 similarity index 100% rename from litserve/model.py rename to app/litserve/model.py diff --git a/litserve_serve.py b/app/litserve_serve.py old mode 100644 new mode 100755 similarity index 96% rename from litserve_serve.py rename to app/litserve_serve.py index 22bb5d8..c57d2e6 --- a/litserve_serve.py +++ b/app/litserve_serve.py @@ -6,10 +6,9 @@ from minio import Minio import litserve as ls from PIL import Image import io -import base64 from diffusers import Flux2KleinPipeline -from utils.new_oss_client import oss_get_image, oss_upload_image, MINIO_URL, MINIO_ACCESS, MINIO_SECRET, MINIO_SECURE +from app.utils.new_oss_client import oss_get_image, oss_upload_image, MINIO_URL, MINIO_ACCESS, MINIO_SECRET, MINIO_SECURE minio_client = Minio(MINIO_URL, access_key=MINIO_ACCESS, secret_key=MINIO_SECRET, secure=MINIO_SECURE) @@ -117,9 +116,10 @@ class FluxKleinAPI(ls.LitAPI): images = payload.get("images", []) prompt = payload.get("prompt", "") gen = torch.Generator(device=self.device) - output = {} + seed = gen.seed() + print(f"本次使用的随机种子是: {seed}") if images: - output['im'] = self.pipe( + output = self.pipe( image=images, prompt=prompt, height=payload.get("height", 512), diff --git a/utils/new_oss_client.py b/app/utils/new_oss_client.py old mode 100644 new mode 100755 similarity index 96% rename from utils/new_oss_client.py rename to app/utils/new_oss_client.py index 5c112d2..cc1c187 --- a/utils/new_oss_client.py +++ b/app/utils/new_oss_client.py @@ -61,7 +61,7 @@ def oss_upload_image(oss_client, bucket, object_name, image_bytes): if __name__ == '__main__': - url = "test/fida_generate_image/692932cfecd9499688899812737a369c.png" + url = "test/fida_generate_image/9fea0a597d884c81a5a4c8381b7bae2c.png" img = oss_get_image(oss_client=minio_client, bucket=url.split('/')[0], object_name=url[url.find('/') + 1:]) img.show() img.save("result.png") diff --git a/assets/i2i_klein.jpg b/assets/i2i_klein.jpg old mode 100644 new mode 100755 diff --git a/assets/i2i_upsample_example.png b/assets/i2i_upsample_example.png old mode 100644 new mode 100755 diff --git a/assets/i2i_upsample_input.png b/assets/i2i_upsample_input.png old mode 100644 new mode 100755 diff --git a/assets/klein_benchmark.jpg b/assets/klein_benchmark.jpg old mode 100644 new mode 100755 diff --git a/assets/t2i_klein_others.jpg b/assets/t2i_klein_others.jpg old mode 100644 new mode 100755 diff --git a/assets/t2i_klein_realism.jpg b/assets/t2i_klein_realism.jpg old mode 100644 new mode 100755 diff --git a/assets/t2i_upsample_example.png b/assets/t2i_upsample_example.png old mode 100644 new mode 100755 diff --git a/assets/teaser_editing.png b/assets/teaser_editing.png old mode 100644 new mode 100755 diff --git a/assets/teaser_generation.png b/assets/teaser_generation.png old mode 100644 new mode 100755 diff --git a/client.py b/client.py old mode 100644 new mode 100755 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100755 index 0000000..ba8ee59 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,19 @@ +services: + flux2_klein: + restart: always + build: + context: . + dockerfile: Dockerfile + working_dir: /app + volumes: + - ./app:/app/app + - /etc/localtime:/etc/localtime:ro + ports: + - "14202:8451" + deploy: + resources: + reservations: + devices: + - driver: nvidia + device_ids: [ '0' ] + capabilities: [ gpu ] \ No newline at end of file diff --git a/docs/flux2_dev_hf.md b/docs/flux2_dev_hf.md old mode 100644 new mode 100755 diff --git a/docs/flux2_with_prompt_upsampling.md b/docs/flux2_with_prompt_upsampling.md old mode 100644 new mode 100755 diff --git a/model_cards/FLUX.2-dev.md b/model_cards/FLUX.2-dev.md old mode 100644 new mode 100755 diff --git a/model_licenses/LICENSE-FLUX-DEV b/model_licenses/LICENSE-FLUX-DEV old mode 100644 new mode 100755 diff --git a/model_licenses/LICENSE-FLUX-NON-COMMERICAL b/model_licenses/LICENSE-FLUX-NON-COMMERICAL old mode 100644 new mode 100755 diff --git a/pyproject.toml b/pyproject.toml old mode 100644 new mode 100755 index d69229f..3400a3b --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ dependencies = [ "datetime>=6.0", "litserve>=0.2.17", "minio>=7.2.20", + "diffusers", ] [project.optional-dependencies] @@ -46,3 +47,6 @@ quote-style = "double" indent-style = "space" line-ending = "auto" docstring-code-format = true + +[tool.uv.sources] +diffusers = { git = "https://github.com/huggingface/diffusers.git" } diff --git a/result1.png b/result1.png deleted file mode 100644 index 075a26e..0000000 Binary files a/result1.png and /dev/null differ diff --git a/scripts/cli.py b/scripts/cli.py old mode 100644 new mode 100755 diff --git a/src/flux2/autoencoder.py b/src/flux2/autoencoder.py old mode 100644 new mode 100755 diff --git a/src/flux2/model.py b/src/flux2/model.py old mode 100644 new mode 100755 diff --git a/src/flux2/openrouter_api_client.py b/src/flux2/openrouter_api_client.py old mode 100644 new mode 100755 diff --git a/src/flux2/sampling.py b/src/flux2/sampling.py old mode 100644 new mode 100755 diff --git a/src/flux2/system_messages.py b/src/flux2/system_messages.py old mode 100644 new mode 100755 diff --git a/src/flux2/text_encoder.py b/src/flux2/text_encoder.py old mode 100644 new mode 100755 diff --git a/src/flux2/util.py b/src/flux2/util.py old mode 100644 new mode 100755 diff --git a/src/flux2/watermark.py b/src/flux2/watermark.py old mode 100644 new mode 100755 diff --git a/test.py b/test.py deleted file mode 100644 index f461f8b..0000000 --- a/test.py +++ /dev/null @@ -1,31 +0,0 @@ -import datetime -import time - -import torch -from PIL import Image -from diffusers import Flux2KleinPipeline - -device = "cuda" -dtype = torch.bfloat16 - -pipe = Flux2KleinPipeline.from_pretrained("black-forest-labs/FLUX.2-klein-4B", torch_dtype=dtype, is_distilled=False) -pipe.to(device) # save some VRAM by offloading the model to CPUsave some VRAM by offloading the model to CPU - -timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") -prompt = "" -num_inference_steps = 4 -input_image = Image.open("result1.png") - -start_time = time.time() -image = pipe( - image=input_image, - prompt=prompt, - height=768, - width=512, - guidance_scale=1.0, - num_inference_steps=num_inference_steps, - # generator=torch.Generator(device=device).manual_seed(3) -).images[0] - -image.save(f"{timestamp}_{num_inference_steps}steps.png") -print(f"infer time : {time.time() - start_time}") diff --git a/uv.lock b/uv.lock old mode 100644 new mode 100755 index 45fd8c1..8cb7d13 --- a/uv.lock +++ b/uv.lock @@ -244,6 +244,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cf/7a/ea0f3e3ea74be36fc7cf54f966cde732a3de72697983cdb5646b0a4dacde/datetime-6.0-py3-none-any.whl", hash = "sha256:d19988f0657a4e72c9438344157254a8dcad6aea8cd5ae70a5d1b5a75e5dc930", size = 52637, upload-time = "2025-11-25T08:00:33.077Z" }, ] +[[package]] +name = "diffusers" +version = "0.38.0.dev0" +source = { git = "https://github.com/huggingface/diffusers.git#11a3284cee024bfff017408b303d18e88981d2ea" } +dependencies = [ + { name = "filelock" }, + { name = "httpx" }, + { name = "huggingface-hub" }, + { name = "importlib-metadata" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pillow" }, + { name = "regex" }, + { name = "requests" }, + { name = "safetensors" }, +] + [[package]] name = "distro" version = "1.9.0" @@ -317,6 +334,7 @@ source = { editable = "." } dependencies = [ { name = "accelerate" }, { name = "datetime" }, + { name = "diffusers" }, { name = "einops" }, { name = "fire" }, { name = "litserve" }, @@ -337,6 +355,7 @@ dev = [ requires-dist = [ { name = "accelerate", specifier = "==1.12.0" }, { name = "datetime", specifier = ">=6.0" }, + { name = "diffusers", git = "https://github.com/huggingface/diffusers.git" }, { name = "einops", specifier = "==0.8.1" }, { name = "fire", specifier = "==0.7.1" }, { name = "litserve", specifier = ">=0.2.17" }, @@ -468,6 +487,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, ] +[[package]] +name = "importlib-metadata" +version = "8.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f3/49/3b30cad09e7771a4982d9975a8cbf64f00d4a1ececb53297f1d9a7be1b10/importlib_metadata-8.7.1.tar.gz", hash = "sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb", size = 57107, upload-time = "2025-12-21T10:00:19.278Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl", hash = "sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151", size = 27865, upload-time = "2025-12-21T10:00:18.329Z" }, +] + [[package]] name = "jinja2" version = "3.1.6" @@ -1697,6 +1728,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl", hash = "sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec", size = 171598, upload-time = "2026-01-10T09:23:45.395Z" }, ] +[[package]] +name = "zipp" +version = "3.23.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547, upload-time = "2025-06-08T17:06:39.4Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload-time = "2025-06-08T17:06:38.034Z" }, +] + [[package]] name = "zope-interface" version = "8.2"