diff --git a/LICENSE b/LICENSE index 4e2c444c5..416373ad2 100644 --- a/LICENSE +++ b/LICENSE @@ -336,70 +336,6 @@ See the License for the specific language governing permissions and limitations under the License. - > demo/Diffusion/utilities.py - > demo/Diffusion/stable_video_diffusion_pipeline.py - - HuggingFace diffusers library. - - Copyright 2024 The HuggingFace Team. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - > demo/Diffusion/utils_sd3/sd3_impls.py - > demo/Diffusion/utils_sd3/other_impls.py - > demo/Diffusion/utils_sd3/mmdit.py - > demo/Diffusion/stable_diffusion_3_pipeline.py - - MIT License - - Copyright (c) 2024 Stability AI - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - > demo/Diffusion/utilities.py - - ModelScope library. - - Copyright (c) Alibaba, Inc. and its affiliates. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - > plugin/scatterElementsPlugin/atomics.cuh > plugin/scatterElementsPlugin/reducer.cuh > plugin/scatterElementsPlugin/scatterElementsPluginKernel.cu diff --git a/demo/Diffusion/.gitignore b/demo/Diffusion/.gitignore deleted file mode 100644 index bcba77164..000000000 --- a/demo/Diffusion/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -__pycache__/ -onnx/ -engine/ -output/ -pytorch_model/ -artifacts_cache/ diff --git a/demo/Diffusion/README.md b/demo/Diffusion/README.md deleted file mode 100755 index 2bcde3186..000000000 --- a/demo/Diffusion/README.md +++ /dev/null @@ -1,538 +0,0 @@ -# Introduction - -This demo application ("demoDiffusion") showcases the acceleration of Stable Diffusion and ControlNet pipeline using TensorRT. - -# Setup - -### Clone the TensorRT OSS repository - -```bash -git clone git@github.com:NVIDIA/TensorRT.git -cd TensorRT -``` - -### Launch NVIDIA pytorch container - -Install nvidia-docker using [these intructions](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker). - -```bash -# Create a directory for persistent dependencies -mkdir -p deps - -# Launch container with volume mounts -docker run --rm -it --gpus all \ - -v $PWD:/workspace \ - -v $PWD/deps:/workspace/deps \ - nvcr.io/nvidia/pytorch:26.03-py3 /bin/bash -``` - -> **NOTE:** Mounting `/workspace/deps` as a volume ensures dependencies persist across container restarts. After initial installation, subsequent container launches will reuse the installed dependencies. - -NOTE: The demo supports CUDA>=13.0 - -### Install the required packages - -This demo uses a family-based dependency management system. Install dependencies for the model families you want to use: - -**Install all dependencies (recommended for first-time users):** -```bash -python3 setup.py all -``` - -**Or install specific model families:** -```bash -# SD family: SD 1.4, SDXL, SD3, SD3.5, SVD (Stable Video Diffusion), Stable Cascade -python3 setup.py sd - -# Flux family: Flux.1-dev, Flux.1-schnell, Flux.1-Canny, Flux.1-Depth, Flux.1-Kontext -python3 setup.py flux - -# Cosmos family: Cosmos-Predict2 text2image, video2world -python3 setup.py cosmos -``` - -**Additional options:** -```bash -# Force reinstall even if already installed -python3 setup.py all --force - -# Install dependencies to a custom location -# Option 1 (recommended): set the env var and install -export TENSORRT_DIFFUSION_DEPS_ROOT=/custom/path/deps -python3 setup.py all - -# Option 2: install to a path without changing this shell -# Remember to export the env var in the environment that runs the demos, -# so deps.configure() can find the custom path. -python3 setup.py all --deps-root /custom/path/deps -# Then, before running any demo scripts: -export TENSORRT_DIFFUSION_DEPS_ROOT=/custom/path/deps -``` - -**Check installation status:** -```bash -python3 -c "from demo_diffusion import deps; deps.print_status()" -``` - -Check your installed TensorRT version using: -```bash -python3 -c 'import tensorrt; print(tensorrt.__version__)' -``` - -> NOTE: Alternatively, you can download and install TensorRT packages from [NVIDIA TensorRT Developer Zone](https://developer.nvidia.com/tensorrt). - -> NOTE: demoDiffusion has been tested on systems with NVIDIA H100, A100, L40, T4, and RTX4090 GPUs, and the following software configuration. - - -# Running demoDiffusion - -### Review usage instructions for the supported pipelines - -```bash -python3 demo_txt2img.py --help -python3 demo_img2img.py --help -python3 demo_controlnet.py --help -python3 demo_txt2img_xl.py --help -python3 demo_txt2img_flux.py --help -python3 demo_txt2vid_wan.py --help -``` - -### HuggingFace user access token - -To download model checkpoints for the Stable Diffusion pipelines, obtain a `read` access token to HuggingFace Hub. See [instructions](https://huggingface.co/docs/hub/security-tokens). - -```bash -export HF_TOKEN= -``` - -### Generate an image guided by a text prompt - -```bash -python3 demo_txt2img.py "a beautiful photograph of Mt. Fuji during cherry blossom" --hf-token=$HF_TOKEN -``` - -### Faster Text-to-image using SD1.4 INT8 & FP8 quantization using ModelOpt - -Run the below command to generate an image with SD1.4 in INT8 - -```bash -python3 demo_txt2img.py "a beautiful photograph of Mt. Fuji during cherry blossom" --hf-token=$HF_TOKEN --int8 -``` - -Run the below command to generate an image with SD1.4 in FP8. (FP8 is only supported on Hopper and Ada.) - -```bash -python3 demo_txt2img.py "a beautiful photograph of Mt. Fuji during cherry blossom" --hf-token=$HF_TOKEN --fp8 -``` - -### Generate an image guided by an initial image and a text prompt - -```bash -wget https://raw.githubusercontent.com/CompVis/stable-diffusion/main/assets/stable-samples/img2img/sketch-mountains-input.jpg -O sketch-mountains-input.jpg - -python3 demo_img2img.py "A fantasy landscape, trending on artstation" --hf-token=$HF_TOKEN --input-image=sketch-mountains-input.jpg -``` - -### Generate an image with ControlNet guided by image(s) and text prompt(s) - -```bash -python3 demo_controlnet.py "Stormtrooper's lecture in beautiful lecture hall" --controlnet-type depth --hf-token=$HF_TOKEN --denoising-steps 20 --onnx-dir=onnx-cnet-depth --engine-dir=engine-cnet-depth -``` - -> NOTE: `--input-image` must be a pre-processed image corresponding to `--controlnet-type`. If unspecified, a sample image will be downloaded. Supported controlnet types include: `canny`, `depth`, `hed`, `mlsd`, `normal`, `openpose`, `scribble`, and `seg`. - -Examples: -“” - -#### Combining multiple conditionings - -Multiple ControlNet types can also be specified to combine the conditionings. While specifying multiple conditionings, controlnet scales should also be provided. The scales signify the importance of each conditioning in relation with the other. For example, to condition using `openpose` and `canny` with scales of 1.0 and 0.8 respectively, the arguments provided would be `--controlnet-type openpose canny` and `--controlnet-scale 1.0 0.8`. Note that the number of controlnet scales provided should match the number of controlnet types. - -### Generate an image with Stable Diffusion XL guided by a single text prompt - -> **NOTE:** SDXL and later Stable Diffusion models require sd dependencies to be installed. Install with: `python3 setup.py sd` - -Run the below command to generate an image with Stable Diffusion XL - -```bash -python3 demo_txt2img_xl.py "a photo of an astronaut riding a horse on mars" --hf-token=$HF_TOKEN --version=xl-1.0 -``` - -The optional refiner model may be enabled by specifying `--enable-refiner` and separate directories for storing refiner onnx and engine files using `--onnx-refiner-dir` and `--engine-refiner-dir` respectively. - -```bash -python3 demo_txt2img_xl.py "a photo of an astronaut riding a horse on mars" --hf-token=$HF_TOKEN --version=xl-1.0 --enable-refiner --onnx-refiner-dir=onnx-refiner --engine-refiner-dir=engine-refiner -``` - -### Generate an image with Stable Diffusion XL with ControlNet guided by an image and a text prompt - -```bash -python3 demo_controlnet.py "A beautiful bird with rainbow colors" --controlnet-type canny --hf-token=$HF_TOKEN --denoising-steps 20 --onnx-dir=onnx-cnet --engine-dir=engine-cnet --version xl-1.0 -``` - -> NOTE: Currently only `--controlnet-type canny` is supported. `--input-image` must be a pre-processed image corresponding to `--controlnet-type canny`. If unspecified, a sample image will be downloaded. - -> NOTE: FP8 quantization (`--fp8`) is supported. - -### Generate an image guided by a text prompt, and using specified LoRA model weight updates - -```bash -# FP16 -python3 demo_txt2img_xl.py "Picture of a rustic Italian village with Olive trees and mountains" --version=xl-1.0 --lora-path "ostris/crayon_style_lora_sdxl" "ostris/watercolor_style_lora_sdxl" --lora-weight 0.3 0.7 --onnx-dir onnx-sdxl-lora --engine-dir engine-sdxl-lora --build-enable-refit - -# FP8 -python3 demo_txt2img_xl.py "Picture of a rustic Italian village with Olive trees and mountains" --version=xl-1.0 --lora-path "ostris/crayon_style_lora_sdxl" "ostris/watercolor_style_lora_sdxl" --lora-weight 0.3 0.7 --onnx-dir onnx-sdxl-lora --engine-dir engine-sdxl-lora --fp8 -``` - -### Faster Text-to-image using SDXL INT8 & FP8 quantization using ModelOpt - -Run the below command to generate an image with Stable Diffusion XL in INT8 - -```bash -python3 demo_txt2img_xl.py "a photo of an astronaut riding a horse on mars" --version xl-1.0 --onnx-dir onnx-sdxl --engine-dir engine-sdxl --int8 -``` - -Run the below command to generate an image with Stable Diffusion XL in FP8. (FP8 is only supported on Hopper and Ada.) - -```bash -python3 demo_txt2img_xl.py "a photo of an astronaut riding a horse on mars" --version xl-1.0 --onnx-dir onnx-sdxl --engine-dir engine-sdxl --fp8 -``` - -> Note that INT8 & FP8 quantization is only supported for SDXL, and won't work with LoRA weights. FP8 quantization is only supported on Hopper and Ada. Some prompts may produce better inputs with fewer denoising steps (e.g. `--denoising-steps 20`) but this will repeat the calibration, ONNX export, and engine building processes for the U-Net. - -For step-by-step tutorials to run INT8 & FP8 inference on stable diffusion models, please refer to examples in [TensorRT ModelOpt diffusers sample](https://github.com/NVIDIA/TensorRT-Model-Optimizer/tree/main/diffusers). - -### Faster Text-to-Image using SDXL Turbo - -Produce coherent images in just 1 step. Note: SDXL Turbo works best for 512x512 resolution, EulerA scheduler and classifier-free-guidance disabled. - -```bash -python3 demo_txt2img_xl.py "Einstein" --version xl-turbo --onnx-dir onnx-sdxl-turbo --engine-dir engine-sdxl-turbo --denoising-steps 1 --scheduler EulerA --guidance-scale 0.0 --width 512 --height 512 -``` - -### Generate an image guided by a text prompt using Stable Diffusion 3 and its variants - -Run the command below to generate an image using Stable Diffusion 3 and Stable Diffusion 3.5 - -```bash -# Stable Diffusion 3 -python3 demo_txt2img_sd3.py "A vibrant street wall covered in colorful graffiti, the centerpiece spells \"SD3 MEDIUM\", in a storm of colors" --version sd3 --hf-token=$HF_TOKEN - -# Stable Diffusion 3.5-medium -python3 demo_txt2img_sd35.py "a beautiful photograph of Mt. Fuji during cherry blossom" --version=3.5-medium --denoising-steps=30 --guidance-scale 3.5 --hf-token=$HF_TOKEN --bf16 --download-onnx-models - -# Stable Diffusion 3.5-large -python3 demo_txt2img_sd35.py "a beautiful photograph of Mt. Fuji during cherry blossom" --version=3.5-large --denoising-steps=30 --guidance-scale 3.5 --hf-token=$HF_TOKEN --bf16 --download-onnx-models - -# Stable Diffusion 3.5-large FP8 -python3 demo_txt2img_sd35.py "a beautiful photograph of Mt. Fuji during cherry blossom" --version=3.5-large --denoising-steps=30 --guidance-scale 3.5 --hf-token=$HF_TOKEN --fp8 --download-onnx-models --onnx-dir onnx_35_fp8/ --engine-dir engine_35_fp8/ -``` - -You can also specify an input image conditioning as shown below - -```bash -wget https://raw.githubusercontent.com/CompVis/latent-diffusion/main/data/inpainting_examples/overture-creations-5sI6fQgYIuo.png -O dog-on-bench.png - -# Stable Diffusion 3 -python3 demo_txt2img_sd3.py "dog wearing a sweater and a blue collar" --version sd3 --input-image dog-on-bench.png --hf-token=$HF_TOKEN -``` - -Note that a denosing-percentage is applied to the number of denoising-steps when an input image conditioning is provided. Its default value is set to 0.6. This parameter can be updated using `--denoising-percentage` - -### Generate an image with Stable Diffusion v3.5-large with ControlNet guided by an image and a text prompt - -```bash -# Depth BF16 -python3 demo_controlnet_sd35.py "a photo of a man" --controlnet-type depth --hf-token=$HF_TOKEN --denoising-steps 40 --guidance-scale 4.5 --bf16 --download-onnx-models --low-vram - -# Depth FP8 -python3 demo_controlnet_sd35.py "a photo of a man" --version=3.5-large --fp8 --controlnet-type depth --download-onnx-models --denoising-steps=40 --guidance-scale 4.5 --hf-token=$HF_TOKEN --low-vram - -# Canny BF16 -python3 demo_controlnet_sd35.py "A Night time photo taken by Leica M11, portrait of a Japanese woman in a kimono, looking at the camera, Cherry blossoms" --controlnet-type canny --hf-token=$HF_TOKEN --denoising-steps 60 --guidance-scale 3.5 --bf16 --download-onnx-models --low-vram - -# Canny FP8 -python3 demo_controlnet_sd35.py "A Night time photo taken by Leica M11, portrait of a Japanese woman in a kimono, looking at the camera, Cherry blossoms" --version=3.5-large --fp8 --controlnet-type canny --hf-token=$HF_TOKEN --denoising-steps 60 --guidance-scale 3.5 --low-vram --download-onnx-models - -# Blur -python3 demo_controlnet_sd35.py "generated ai art, a tiny, lost rubber ducky in an action shot close-up, surfing the humongous waves, inside the tube, in the style of Kelly Slater" --controlnet-type blur --hf-token=$HF_TOKEN --denoising-steps 60 --guidance-scale 3.5 --bf16 --download-onnx-models --low-vram -``` - -### Generate a video guided by an initial image using Stable Video Diffusion - -Download the pre-exported ONNX model - -```bash -pip install -U "huggingface_hub[cli]" -hf download stabilityai/stable-video-diffusion-img2vid-xt-1-1-tensorrt --local-dir onnx-svd-xt-1-1 -``` - -SVD-XT-1.1 (25 frames at resolution 576x1024) - -```bash -python3 demo_img2vid.py --version svd-xt-1.1 --onnx-dir onnx-svd-xt-1-1 --engine-dir engine-svd-xt-1-1 --hf-token=$HF_TOKEN -``` - -Run the command below to generate a video in FP8. - -```bash -python3 demo_img2vid.py --version svd-xt-1.1 --onnx-dir onnx-svd-xt-1-1 --engine-dir engine-svd-xt-1-1 --hf-token=$HF_TOKEN --fp8 -``` - -> NOTE: There is a bug in HuggingFace, you can workaround with following this [PR](https://github.com/huggingface/diffusers/pull/6562/files) - -``` -if torch.is_tensor(num_frames): - num_frames = num_frames.item() -emb = emb.repeat_interleave(num_frames, dim=0) -``` - -You may also specify a custom conditioning image using `--input-image`: - -```bash -python3 demo_img2vid.py --version svd-xt-1.1 --onnx-dir onnx-svd-xt-1-1 --engine-dir engine-svd-xt-1-1 --input-image https://www.hdcarwallpapers.com/walls/2018_chevrolet_camaro_zl1_nascar_race_car_2-HD.jpg --hf-token=$HF_TOKEN -``` - -NOTE: The min and max guidance scales are configured using --min-guidance-scale and --max-guidance-scale respectively. - -### Generate an image guided by a text prompt using Stable Cascade - -Run the below command to generate an image using Stable Cascade - -```bash -python3 demo_stable_cascade.py --onnx-opset=16 "Anthropomorphic cat dressed as a pilot" --onnx-dir onnx-sc --engine-dir engine-sc -``` - -The lite versions of the models are also supported using the command below - -```bash -python3 demo_stable_cascade.py --onnx-opset=16 "Anthropomorphic cat dressed as a pilot" --onnx-dir onnx-sc-lite --engine-dir engine-sc-lite --lite -``` - -> NOTE: The pipeline is only enabled for the BF16 model weights - -> NOTE: The pipeline only supports ONNX export using Opset 16. - -> NOTE: The denoising steps and guidance scale for the Prior and Decoder models are configured using --prior-denoising-steps, --prior-guidance-scale, --decoder-denoising-steps, and --decoder-guidance-scale respectively. - -### Generating Images with Flux - -> **NOTE:** Flux models require Flux family dependencies. Install with: `python3 setup.py flux` - -#### 1. Generate an Image from a Text Prompt - -##### Run Flux.1-Dev - -NOTE: Pass `--download-onnx-models` to avoid native ONNX export and download the ONNX models from [Black Forest Labs' collection](https://huggingface.co/collections/black-forest-labs/flux1-onnx-679d06b7579583bd84c8ef83). It is only supported for BF16, FP8, and FP4 pipelines. - -```bash -# FP16 (requires >48GB VRAM for native export) -python3 demo_txt2img_flux.py "a beautiful photograph of Mt. Fuji during cherry blossom" --hf-token=$HF_TOKEN - -# BF16 -python3 demo_txt2img_flux.py "a beautiful photograph of Mt. Fuji during cherry blossom" --hf-token=$HF_TOKEN --bf16 --download-onnx-models - -# FP8 -python3 demo_txt2img_flux.py "a beautiful photograph of Mt. Fuji during cherry blossom" --hf-token=$HF_TOKEN --quantization-level 4 --fp8 --download-onnx-models - -# FP4 -python3 demo_txt2img_flux.py "a beautiful photograph of Mt. Fuji during cherry blossom" --hf-token=$HF_TOKEN --fp4 --download-onnx-models -``` - -##### Run Flux.1-Schnell - -```bash -# FP16 (requires >48GB VRAM for native export) -python3 demo_txt2img_flux.py "a beautiful photograph of Mt. Fuji during cherry blossom" --hf-token=$HF_TOKEN --version="flux.1-schnell" - -# BF16 -python3 demo_txt2img_flux.py "a beautiful photograph of Mt. Fuji during cherry blossom" --hf-token=$HF_TOKEN --version="flux.1-schnell" --bf16 --download-onnx-models - -# FP8 -python3 demo_txt2img_flux.py "a beautiful photograph of Mt. Fuji during cherry blossom" --hf-token=$HF_TOKEN --version="flux.1-schnell" --quantization-level 4 --fp8 --download-onnx-models - -# FP4 -python3 demo_txt2img_flux.py "a beautiful photograph of Mt. Fuji during cherry blossom" --hf-token=$HF_TOKEN --version="flux.1-schnell" --fp4 --download-onnx-models -``` - ---- - -#### 2. Generate an Image from an Initial Image + Text Prompt - -Download an example input image: - -```bash -wget "https://miro.medium.com/v2/resize:fit:640/format:webp/1*iD8mUonHMgnlP0qrSx3qPg.png" -O yellow.png -``` - -Run the image-to-image pipeline: - -```bash -python3 demo_img2img_flux.py "A home with 2 floors and windows. The front door is purple" --hf-token=$HF_TOKEN --input-image yellow.png --image-strength 0.95 --bf16 --onnx-dir onnx-flux-dev/bf16 --engine-dir engine-flux-dev/ -``` - ---- - -#### 3. Generate an Image Using Flux ControlNet - -##### Download the Control Image - -```bash -wget https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/robot.png -``` - -##### Calibration Data for native ONNX export (FP8 Pipeline) - -FP8 ControlNet pipelines require downloading a calibration dataset and providing the path. You can use the datasets provided by Black Forest Labs here: [depth](https://drive.google.com/file/d/1DFfhOSrTlKfvBFLcD2vAALwwH4jSGdGk/view) | [canny](https://drive.google.com/file/d/1dRoxOL-vy3tSAesyqBSJoUWsbkMwv3en/view) - -You can use the `--calibraton-dataset` flag to specify the path, which is set to `./{depth/canny}-eval/benchmark` by default if not provided. Note that the dataset should have `inputs/` and `prompts/` underneath the provided path, matching the format of the BFL dataset. - -##### Depth ControlNet - -```bash -# BF16 -python3 demo_img2img_flux.py "A robot made of exotic candies and chocolates of different kinds. The background is filled with confetti and celebratory gifts." --version="flux.1-dev-depth" --hf-token=$HF_TOKEN --guidance-scale 10 --control-image robot.png --bf16 --denoising-steps 30 --download-onnx-models - -# FP8 using pre-exported ONNX models -python3 demo_img2img_flux.py "A robot made of exotic candies" --version="flux.1-dev-depth" --hf-token=$HF_TOKEN --guidance-scale 10 --control-image robot.png --fp8 --denoising-steps 30 --download-onnx-models --build-static-batch --quantization-level 4 - -# FP8 using native ONNX export -rm -rf onnx/* engine/* && python3 demo_img2img_flux.py "A robot made of exotic candies" --version="flux.1-dev-depth" --hf-token=$HF_TOKEN --guidance-scale 10 --control-image robot.png --quantization-level 4 --fp8 --denoising-steps 30 - -# FP4 -python3 demo_img2img_flux.py "A robot made of exotic candies" --version="flux.1-dev-depth" --hf-token=$HF_TOKEN --guidance-scale 10 --control-image robot.png --fp4 --denoising-steps 30 --download-onnx-models --build-static-batch -``` - -##### Canny ControlNet - -```bash -# BF16 -python3 demo_img2img_flux.py "a robot made out of gold" --version="flux.1-dev-canny" --hf-token=$HF_TOKEN --guidance-scale 30 --control-image robot.png --bf16 --denoising-steps 30 --download-onnx-models - -# FP8 using pre-exported ONNX models -python3 demo_img2img_flux.py "a robot made out of gold" --version="flux.1-dev-canny" --hf-token=$HF_TOKEN --guidance-scale 30 --control-image robot.png --fp8 --denoising-steps 30 --download-onnx-models --build-static-batch --quantization-level 4 - -# FP8 using native ONNX export -rm -rf onnx/* engine/* && python3 demo_img2img_flux.py "a robot made out of gold" --version="flux.1-dev-canny" --hf-token=$HF_TOKEN --guidance-scale 30 --control-image robot.png --quantization-level 4 --fp8 --denoising-steps 30 --calibration-dataset {custom/dataset/path} - -# FP4 -python3 demo_img2img_flux.py "a robot made out of gold" --version="flux.1-dev-canny" --hf-token=$HF_TOKEN --guidance-scale 30 --control-image robot.png --fp4 --denoising-steps 30 --download-onnx-models --build-static-batch -``` - -#### 4. Generate an Image Using Flux LoRA - -FLUX supports loading LoRA for Flux.1-Dev and Flux.1-Schnell. Make sure the target lora is compatible with the transformer model. Below is an example of using a [water color Flux LoRA](https://huggingface.co/SebastianBodza/flux_lora_aquarel_watercolor) - -```bash -# FP16 -python3 demo_txt2img_flux.py "A painting of a barista creating an intricate latte art design, with the 'Coffee Creations' logo skillfully formed within the latte foam. In a watercolor style, AQUACOLTOK. White background." --hf-token=$HF_TOKEN --lora-path "SebastianBodza/flux_lora_aquarel_watercolor" --lora-weight 1.0 --onnx-dir=onnx-flux-lora --engine-dir=engine-flux-lora - -# FP8 -python3 demo_txt2img_flux.py "A painting of a barista creating an intricate latte art design, with the 'Coffee Creations' logo skillfully formed within the latte foam. In a watercolor style, AQUACOLTOK. White background." --hf-token=$HF_TOKEN --lora-path "SebastianBodza/flux_lora_aquarel_watercolor" --lora-weight 1.0 --onnx-dir=onnx-flux-lora --engine-dir=engine-flux-lora --fp8 -``` - -#### 5. Edit an Image using Flux Kontext - -```bash -wget https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/cat.png - -# BF16 -python3 demo_img2img_flux.py "Add a hat to the cat" --version="flux.1-kontext-dev" --hf-token=$HF_TOKEN --guidance-scale 2.5 --kontext-image cat.png --denoising-steps 28 --bf16 --onnx-dir onnx-kontext --engine-dir engine-kontext --download-onnx-models - -# FP8 -python3 demo_img2img_flux.py "Add a hat to the cat" --version="flux.1-kontext-dev" --hf-token=$HF_TOKEN --guidance-scale 2.5 --kontext-image cat.png --denoising-steps 28 --fp8 --onnx-dir onnx-kontext-fp8 --engine-dir engine-kontext-fp8 --download-onnx-models --quantization-level 4 - -# FP4 -python3 demo_img2img_flux.py "Add a hat to the cat" --version="flux.1-kontext-dev" --hf-token=$HF_TOKEN --guidance-scale 2.5 --kontext-image cat.png --denoising-steps 28 --fp4 --onnx-dir onnx-kontext-fp4 --engine-dir engine-kontext-fp4 --download-onnx-models -``` ---- - -#### 5. Export ONNX Models Only (Skip Inference) - -Use the `--onnx-export-only` flag to export ONNX models on a higher-VRAM device. The exported ONNX models can be used on a device with lower VRAM for the engine build and inference steps. - -```bash -python3 demo_txt2img_flux.py "a beautiful photograph of Mt. Fuji during cherry blossom" --hf-token=$HF_TOKEN --onnx-export-only -``` - ---- - -#### 6. Running Flux on GPUs with Limited Memory - -##### Optimization Flags - -- `--low-vram`: Enables model-offloading for reduced VRAM usage. -- `--ws`: Enables weight streaming in TensorRT engines. -- `--t5-ws-percentage` and `--transformer-ws-percentage`: Set runtime weight streaming budgets. -- `--build-static-batch`: Build all engines using static batch sizes to lower the required activation memory. This will limit supported batch size of these engines for inference to the value specified by `--batch-size`. - -##### FLUX VRAM Requirements Table - -Memory usage captured below excludes the ONNX export step, and assumes use of the `--build-static-batch` flag to reduce activation VRAM usage. Users can either use [pre-exported ONNX models](README.md#download-pre-exported-models-recommended-for-48gb-vram) or export the models separately on a higher-VRAM device using [--onnx-export-only](README.md#4-export-onnx-models-only-skip-inference). - -| Precision | Default VRAM Usage | With `--low-vram` | -| --------- | ------------------ | ----------------- | -| FP16 | 39.3 GB | 23.9 GB | -| BF16 | 35.7 GB | 23.9 GB | -| FP8 | 24.6 GB | 14.9 GB | -| FP4 | 21.67 GB | 11.1 GB | - -NOTE: The FP8 and FP4 Pipelines are supported on Hopper/Ada/Blackwell devices only. The FP4 pipeline is most performant on Blackwell devices. - - -### Run Cosmos2 World Foundation Models - -> **NOTE:** Cosmos models require Cosmos family dependencies. Install with: `python3 setup.py cosmos` - -Select the prompts and export them as below - -```bash -export PROMPT="A close-up shot captures a vibrant yellow scrubber vigorously working on a grimy plate, its bristles moving in circular motions to lift stubborn grease and food residue. The dish, once covered in remnants of a hearty meal, gradually reveals its original glossy surface. Suds form and bubble around the scrubber, creating a satisfying visual of cleanliness in progress. The sound of scrubbing fills the air, accompanied by the gentle clinking of the dish against the sink. As the scrubber continues its task, the dish transforms, gleaming under the bright kitchen lights, symbolizing the triumph of cleanliness over mess." - -export NEGATIVE_PROMPT="The video captures a series of frames showing ugly scenes, static with no motion, motion blur, over-saturation, shaky footage, low resolution, grainy texture, pixelated images, poorly lit areas, underexposed and overexposed scenes, poor color balance, washed out colors, choppy sequences, jerky movements, low frame rate, artifacting, color banding, unnatural transitions, outdated special effects, fake elements, unconvincing visuals, poorly edited content, jump cuts, visual noise, and flickering. Overall, the video is of poor quality." -``` - -#### 1. Generate an Image from a Text Prompt - -##### Run Cosmos-Predict2-2B-Text2Image - -```bash -# BF16 -python3 demo_txt2image_cosmos.py "$PROMPT" --negative-prompt="$NEGATIVE_PROMPT" --hf-token=$HF_TOKEN -``` - -#### 2. Generate a Video guided by an Initial Video Conditioning and a Text Prompt - -##### Run Cosmos-Predict2-2B-Video2World (only PyTorch backend enabled) - -```bash -# BF16 -python3 demo_vid2world_cosmos.py "$PROMPT" --negative-prompt="$NEGATIVE_PROMPT" --hf-token=$HF_TOKEN -``` - - -### Specify Custom Paths for ONNX models and TensorRT engines (FLUX, Stable Diffusion 3.5 and Cosmos only) - -Custom override paths to pre-exported ONNX model files can be provided using `--custom-onnx-paths`. These ONNX models are directly used to build TRT engines without further optimization on the ONNX graphs. Paths should be a comma-separated list of : pairs. For example: `--custom-onnx-paths=transformer:/path/to/transformer.onnx,vae:/path/to/vae.onnx`. Call .get_model_names(...) for the list of supported model names. - -Custom override paths to pre-built engine files can be provided using `--custom-engine-paths`. Paths should be a comma-separated list of : pairs. For example: `--custom-onnx-paths=transformer:/path/to/transformer.plan,vae:/path/to/vae.plan`. - -### Generate a video from a text prompt using Wan - -Run the below command to generate 81 frames of video at 720×1280 resolution using Wan 2.2. Due to the high memory requirements of this model, it is recommended to enable `--low-vram` and use a Blackwell device. - -```bash -# Default (81 frames, 720x1280) with --low-vram enabled -python3 demo_txt2vid_wan.py "A serene bamboo forest with sunlight filtering through the leaves" --hf-token=$HF_TOKEN --low-vram - -# Adjust denoising steps, guidance scales, negative prompt, seed, warmup runs -python3 demo_txt2vid_wan.py "Ocean waves crashing on a beach at sunset" --hf-token=$HF_TOKEN --low-vram --denoising-steps 50 --guidance-scale 4.5 --guidance-scale-2 3.5 --negative-prompt "blurry, low quality, static" --seed 42 --num-warmup-runs 0 -``` - -## Configuration options - -- Noise scheduler can be set using `--scheduler `. Note: not all schedulers are available for every version. -- To accelerate engine building time use `--timing-cache `. The cache file will be created if it does not already exist. Note that performance may degrade if cache files are used across multiple GPU targets. It is recommended to use timing caches only during development. To achieve the best perfromance in deployment, please build engines without timing cache. -- Specify new directories for storing onnx and engine files when switching between versions, LoRAs, ControlNets, etc. This can be done using `--onnx-dir ` and `--engine-dir `. -- Inference performance can be improved by enabling [CUDA graphs](https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#cuda-graphs) using `--use-cuda-graph`. Enabling CUDA graphs requires fixed input shapes, so this flag must be combined with `--build-static-batch` and cannot be combined with `--build-dynamic-shape`. - diff --git a/demo/Diffusion/calibration_data/calibration-images/rocket.png b/demo/Diffusion/calibration_data/calibration-images/rocket.png deleted file mode 100644 index 3f6fef6fa..000000000 Binary files a/demo/Diffusion/calibration_data/calibration-images/rocket.png and /dev/null differ diff --git a/demo/Diffusion/calibration_data/calibration-prompts.txt b/demo/Diffusion/calibration_data/calibration-prompts.txt deleted file mode 100644 index 8b224e6d1..000000000 --- a/demo/Diffusion/calibration_data/calibration-prompts.txt +++ /dev/null @@ -1,1079 +0,0 @@ -Portrait shot of a woman, yellow shirt, photograph -Little girl holding a teddy bear, in the middle of nowhere, photograph -Portrait of an arctic fox in the tundra, light teal and amber, minimalist, photograph -Confused woman, sci - fi, future, blue glow color, orange, hologram, photograph -Symmetrical, macro shot, crying womans face, half of face is organic flowing RGB low poly, depth of field -Beautiful woman future funk psychedelic -Mosaic of a colorful mushroom with intricate patterns, vibrant and detailed, sharp, mosaic background, vector art -Illustration of a man in red hoodie, minimalist, graphic design poster art, dark cyan and sky - blue, honeycore -a bottle of perfume on a clean backdrop, surrounded by fragrant white flowers, product photography, minimalistic, natural light -a bedroom with large windows and modern furniture, gray and gold, luxurious, mid century modern style -an aerial drone shot of the breathtaking landscape of the Bora Bora islands, with sparkling waters under the sun -extreme closeup shot of an old man with a long gray hair and head covered in wrinkles; focused expression looking at camera -Simple flat vector illustration of a woman sitting at the desk with her laptop with a puppy, isolated on white background -Chibi pixel art, game asset for an rpg game on a white background featuring the armor of a dragon sorcerer wielding the power of fire surrounded by a matching item set -a macro wildlife photo of a green frog in a rainforest pond, highly detailed, eye-level shot -kid's coloring book, a happy young girl holding a flower, cartoon, thick lines, black and white, white background -Golden-haired elementary school white boy hugging his black-hair Taiwanese buddy face-to-face on dusk street, unreal engine, greg rutkowski, loish, rhads, beeple, makoto shinkai and lois van baarle, ilya kuvshinov, rossdraws, tom bagshaw, alphonse mucha, global illumination, detailed and intricate environment -Tan skin Anime boy wearing a large black sweater and cat ear beanie with brown hair and eyes, full body, baggy cargo pants, full body, reference -Fawn French Bulldog with big eyes, short legs, and chunky, stocky body eating food -A white goose holding a paint brush -Black, African descent, looks Japanese, wears glasses, Naruto type art, bandage on his nose, male, Anime 2D art, lazy eyes, Japanese earring in one ear, no beard, smiles sinisterly -Male cow fursona wearing a red beanie -a beautiful hyper-realistic anime Lofi, painted by greg rutkowski makoto shinkai takashi takeuchi studio ghibli, akihiko yoshida, anime, clean soft lighting, finely detailed features, high-resolution, perfect art, stunning atmosphere, trending on pixiv fanbox -a woman with a beautiful face is enjoying a summer festival wearing a kimono, long white hair, looks like an older sister with a small body, is holding a traditional Japanese umbrella with a faint smile, her head is facing backwards as if inviting her to play and she is running with her arms behind her, there is also a lock of patterned hair flower -A stunning photograph of a serene mountain lake at sunrise, with crystal-clear reflections and soft pastel skies -A high-resolution image of an ancient oak tree in a lush forest, sunlight filtering through the leaves -An ultra-realistic photograph of the Milky Way galaxy seen from a remote desert, under clear skies -A detailed image of a colorful street market in Marrakech at golden hour, with vibrant fabrics and bustling crowds -A professional photograph of a majestic bald eagle in flight, with a crisp focus on its sharp eyes and detailed feathers -A perfect image of a charming cobblestone street in Prague, with historical buildings and a peaceful early morning atmosphere -A photo-realistic image of a modern city skyline at night, with shimmering lights and reflections on a river -An authentic-looking photograph of the Northern Lights over a snowy Lapland landscape, with vivid colors and clear stars -A high-quality image of a vintage 1950s diner, with classic cars parked outside and a sunset backdrop -An elegant photograph of a grand ballroom from the Victorian era, with ornate decorations and a grand chandelier -A striking photograph of a powerful thunderstorm over the ocean, with dramatic lightning strikes and rolling waves -An image of a peaceful Zen garden with smooth stones, raked sand, and a calming waterfall -A high-resolution photograph of a seasoned fisherman at dawn, casting a net into the sea, with the golden light reflecting off the water -A professional close-up shot of a woman's face, half-illuminated by the sunset, showcasing a detailed texture of her skin and a contemplative expression -An image capturing a street dancer in mid-air during a dynamic breakdance move, with urban graffiti in the background -A vibrant photograph of a group of people dressed in traditional attire at a cultural festival, dancing in a blur of colors and fabrics -A cinematic-style photograph of a lone astronaut in a spacesuit, standing on a rocky alien landscape with Earth visible in the sky above -Capture the quiet intensity in the eyes of a chess grandmaster poised over the board in a high-stakes match -Close-up: A young girl's freckled face, focused and thoughtful, as she reads a book under the shade of an old tree -Underwater photography of a diver among swirling schools of fish, light filtering down from above -Evening falls on a city street musician, his guitar casting long shadows as he strums for the passing crowd -High above the city, a construction worker perches on a steel beam, with a backdrop of the skyline stretching into the distance -Document the intense expression of a potter as they shape a clay vessel, hands and wheel both a blur of motion -A street portrait captures the weathered face of a long-time vendor, his cart a staple in the neighborhood for generations -During golden hour, a group of children race through a field, their silhouettes a dance of joy against the setting sun -Zoomed-in shot capturing the intense focus of a violinist as the bow gracefully sweeps across the strings, emotions etched into their performance -Evening light bathes a street artist in a halo as they spray paint a vibrant mural, the colors telling a story as much as the subject's concentrated gaze -A mid-action image of a chef's hands chopping herbs, with fine details showing flying droplets of water from the fresh greens -On a misty morning, capture the solitary figure of a jogger on a deserted trail, their breath and stride in sync -High in the mountains, a hiker reaches the summit, standing triumphantly with a panoramic view stretching behind them -Illuminated by the soft glow of a desk lamp, a writer pauses, pen in hand, surrounded by stacks of manuscripts, lost in thought -eerie, corruption, beautiful, young woman, sad eyes, tears running down, crying, innocence, light, vaporwave aesthetic, synthwave, colorful, psychedelic, crown, long gown, flowers, bees, butterflies, ribbons, ornate, intricate, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -wolf merged with crow,! photorealistic,! concept art -To every living being, and every living soul. Now cometh the age of the stars. A thousand year voyage under the wisdom of the Moon. Here begins the chill night that encompasses all, reaching the great beyond. Into fear, doubt, and loneliness... As the path stretches into darkness. Mysterious shadow, detailed, digital, trending on artstation, hyper realistic, dark colours, 4k, dark aesthetic, in the style of James C. Christensen -A cowboy cat with big and cute eyes, fine-face, realistic shaded perfect face, fine details. realistic shaded lighting poster by Ilya Kuvshinov katsuhiro otomo ghost-in-the-shell, magali villeneuve, artgerm, Jeremy Lipkin and Michael Garmash, Rob Rey and Kentarõ Miura style, trending on art station -a very beautiful anime cute girl, full body, long wavy blond hair, sky blue eyes, full round face, short smile, fancy top, miniskirt, front view, summer lake setting, cinematic lightning, medium shot, mid-shot, highly detailed, trending on Artstation, Unreal Engine 4k, cinematic wallpaper by Stanley Artgerm Lau, WLOP, Rossdraws, James Jean, Andrei Riabovitchev, Marc Simonetti -close-up portrait of the perfect and symmetrical face of a beautiful Cotton Mill Girl, symmetrical, centered, dramatic angle, ornate, details, smooth, sharp focus, illustration, realistic, cinematic, artstation, award winning, rgb , unreal engine, octane render, cinematic light, macro, depth of field, blur, red light and clouds from the back, highly detailed epic cinematic concept art CG render made in Maya, Blender and Photoshop, octane render, excellent composition, dynamic dramatic cinematic lighting, aesthetic, very inspirational, arthouse by Henri Cartier Bresson -highly detailed portrait of beautiful ethereal woman in ornate clothing, stephen bliss, unreal engine, fantasy art by greg rutkowski, loish, rhads, ferdinand knab, makoto shinkai and lois van baarle, ilya kuvshinov, rossdraws, tom bagshaw, global illumination, radiant light, detailed and intricate environment -Close-up portrait of young asian girl, long blonde hair, dark fantasy, portrait, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -necromancer glowing with purple magic, red hair, female, glacier landscape, D&D, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, art by Artgerm and Greg Rutkowski and Alphonse Mucha -a portrait of riddler, fantasy, sharp focus, intricate, elegant, digital painting, artstation, matte, highly detailed, concept art, illustration, ambient lighting, art by ilya kuvshinov, artgerm, alphonse mucha, and greg rutkowski -duotone dark scifi illustration 3 / 4 portrait of dream as if you live forever live as if you die tomorrow. cinematic lighting mad scientist style. golden ratio accidental renaissance. in the style of jean michel basquiat, beksisnski, and pablo picasso. graffiti art, scifi, fantasy, hyper detailed. octane render. concept art. trending on artstation -elon musk as neo from the matrix, realistic portrait, symmetrical, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha -patrick star with a sad!!! expression slouching on a bench in the bikini bottom, global illumination!!! dim lighting, midnight, cinematic, extremely detailed, beautiful, stunning composition, beautiful light rays, trending on artstation -a girl in a hat with a bouquet of peonies looks out the window at a blooming garden, vivid color, highly detailed, cyberpunk, digital painting, artstation, concept art, matte, sharp focus, art by vrubel -a detailed concept art of a fantasy jingle bell infused with magic, trending on artstation, digital art, 4 k, intricate, octane render, sharp focus -“ dungeons and dragons tabaxi rogue, anthromorphic cat person with a repeating crossbow in a medieval city, small and big, illustration, fantasy, trending on artstation ” -fantasy, book cover, concept art, by greg rutkowski and craig mullins, cozy atmospheric -Amelie Poulain painted by Raphael volumetric lighting, back lighting, rimlight, dramatic lighting, digital painting, highly detailed, artstation, sharp focus, illustration, Artgerm, Jean-L�on G�r�me , ruan jia -soft bokeh front shot photo of a mclaren steampunk concept car, cinematic, fine details, symmetrical, 4 k, digital art, wallpaper -dior runway show, light, shadows, reflections, golden, gold, epic composition, intricate, elegant, volumetric lighting, digital painting, highly detailed, artstation, sharp focus, illustration, concept art, ruan jia, steve mccurry -elven princess assassin, beautiful shadowing, 3 d shadowing, reflective surfaces, illustrated completely, 8 k beautifully detailed pencil illustration, extremely hyper - detailed pencil illustration, intricate, epic composition, very very kawaii, masterpiece, bold complimentary colors. stunning masterfully illustrated by artgerm and range murata. -gorgeous red fox in a suit drinking champagne, digital art, landscape, fantasy art, octane render, ureal engine, high detail, very realistic, by greg rutkowski. by james gurney -an extremely psychedelic portrait of medusa as willy wonka, surreal, lsd, face, detailed, intricate, elegant, lithe, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration -portrait painting of a muscular bloodied mixed girl, ultra realistic, cyberpunk hacknaut, concept art, intricate details, eerie, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and alphonse mucha -concept art for the main character in the award winning film named life is better in pink. the character is a unnaturally beautiful teenage girl with deep dark blue eyes and long curled pink hair, wearing light pink clothes. realistic cg render, anatomically correct, high key lighting, trending on art station, vibrant colors. cute and highly detailed eyes. -beautiful woman, illustration, painting oil on canvas, intricate portrait, detailed, illustration, hd, digital art, overdetailed, art, concept, art -detailed full body concept art illustration oil painting of an anthropomorphic capybara cook in full intricate clothing, biomutant, ultra detailed, digital art, octane render -of a calm ocean with large strange cute happy flying creatures with huge eyes, mouth, long tongue and round teeth appearing from the sky, in the style of gehry and gaudi, macro lens, highly detailed, shallow depth of fielf, digital painting, trending artstation, concept art, illustration, cinematic lighting, vibrant colors, photorealism, epic, octane render -symmetry, samurai, lines, brown skin, machine face, intricate, elegant, highly detailed, digital painting, artstation, cgsociety, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, 8 k -cyberpunk Normani as aeon flux profile picture by Greg Rutkowski, dynamic pose, intricate, futuristic, fantasy, elegant, by Stanley Artgerm Lau, greg rutkowski, thomas kindkade, alphonse mucha, loish, norman Rockwell, metal chrome, shiny, rainy background, asymmetric, afro hair, -chris tucker as dhalsim street fighter, jump kick, 4 k, ultra realistic, detailed focused art by artgerm and greg rutkowski and alphonse mucha -epic scene where mystical dead monk sitting in front of an epic portal, epic angle and pose, symmetrical artwork, 3d with depth of field, blurred background, cybernetic orchid flower butterfly jellyfish crystal dragon, female face skull phoenix bird, translucent, nautilus, energy flow. a highly detailed epic cinematic concept art CG render. made in Maya, Blender and Photoshop, octane render, excellent composition, cinematic dystopian brutalist atmosphere, dynamic dramatic cinematic lighting, aesthetic, very inspirational, arthouse. y Greg Rutkowski, Ilya Kuvshinov, WLOP, Stanley Artgerm Lau, Ruan Jia and Fenghua Zhong -concept art of futuristic modular military base, top angle, oil painting by jama jurabaev, extremely detailed, brush hard, artstation, for aaa game, high quality, brush stroke -portrait of natalie wood eating hamburgers, extra onions and ketchup, luscious patty with sesame seeds, feminine ethereal, handsome, d & d, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -Trending on Artstation, Dark and rainy mega city with towering walls built to block the migrants of the coming climate change migrant crisis showing piles of hundred bodies outside to maintain a quality of life for those who can survive the severe and deadly weather patterns observing small children targeted by advanced military style drones, dystopian, concept art illustration, tilt shift background, wide depth of field, 8k, 35mm film grain -hard surface form fused with organic form fashion outfit design, rainbow iridescent accents, full body frontal view, Peter mohrbacher, zaha hadid, tsutomu nihei, emil melmoth, zdzislaw belsinki, Craig Mullins, yoji shinkawa, trending on artstation, beautifully lit, hyper detailed, insane details, intricate, elite, ornate, elegant, luxury, dramatic lighting, CGsociety, hypermaximalist, golden ratio, octane render, weta digital, micro details, ray trace, 8k, -Gary Busey portrait by Stanley Artgerm Lau, greg rutkowski, thomas kindkade, alphonse mucha, loish, norman Rockwell -( cyberpunk 2 0 7 7, bladerunner 2 0 4 9 ), a complex thick bifurcated robotic cnc surgical arm cybernetic symbiosis hybrid mri 3 d printer machine making a bio chemical lab, art by artgerm and greg rutkowski and alphonse mucha, biomechanical, lens orbs, global illumination, lounge, architectural, f 3 2, -a vampire, male, mid - 3 0 s aged, long black hair, clean shaven, in red and black, high fantasy, realistic, highly detailed, concept art, 8 k. -a elderly wizard casting a black fireball | | pencil sketch, realistic shaded, fine details, realistic shaded lighting poster by greg rutkowski, magali villeneuve, artgerm, jeremy lipkin and michael garmash and rob rey -An elegant green, blue dragon, sitting on a clearing in a flowery jungle, detailed, mtg, digital illustration, trending on artstation -a landscape made of whimsical energy and fibrous magic, artstation landscape, artstation digital, illustrated by eddie mendoza and greg rutkowski, trending on artstation, cgsociety contest winner, cgsociety hd, cgsociety 4 k uhd, 4 k, 8 k -a cosmic painting of prince in space. mindblowing colours, trending on artstation. highly detailed face. -martian chronicles, by jean delville and sophie anderson and mandy jurgens, retrofuturism, moody atmosphere, cinematic atmospheric, cinematic lighting, golden ratio, perfect composition, elegant, no crop, extremely detailed, 4 k, hd, sharp focus, masterpiece, trending on artstation -a highly detailed metahuman 4 k close up render of a seraphim bella hadid monument renaissance in iris van herpen dress schiaparelli in diamonds crystals swarovski and jewelry iridescent in style of alphonse mucha gustav klimt trending on artstation made in unreal engine 4 -fever of the night, a grime tale of the night fever, disco club of the occult, digital painting, artstation, ristan eaton, victo ngai, artgerm, rhads, ross draws, anime styled -symmetrical, full body portrait of a woman with short wavy hair, round face, cottagecore!!, lake, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -fantasy man sitting in library, gold brocaded dark blue clothes, short black hair, books, reddish brown engraved shelves, sharp focus, intricate, extremely detailed, cinematic lighting, smooth, ultra realistic illustration, high fantasy, elegant, artgerm, greg rutkowski, alphonse mucha magali villeneuve -an anthropomorphic deer, fursona!!! by don bluth, by kawacy, trending on artstation, full body -a cartoon squirrel drawn in concept art style -russian poet alexander pushkin and shrek having breakfast together, portrait, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha -beautiful woman on a turquise vespa moped, in the style of artgerm, gerald brom, atey ghailan and mike mignola, vibrant colors and hard shadows and strong rim light, plain background, comic cover art, trending on artstation, masterpiece -a martian landscape, by ralph mac quarrie and francois schuiten and albert bierstadt and ernst haeckel and james jean and john singer sargent, cinematic lighting, moody atmosphere, golden ratio, perfect composition, elegant and stylish look, artstation, concept art, high quality -� anime, full body, a pretty girl taking the college entrance exam, highly intricate detailed, light and shadow effects, intricate, highly detailed, digital painting, art station, concept art, smooth, sharp focus, illustration, advanced digital anime art, art by artgerm and greg rutkowski and alphonse mucha and william - adolphe bouguereau, craig mullins, j. c. leyendecker, atmospheric lighting, detailed face, by makoto shinkai, stanley artgerm lau, wlop, rossdraws � -the second coming of the buddah, by dan mumford and ross tran, cosmic, heavenly, god rays, intricate detail, cinematic, 8 k, cel shaded, unreal engine, featured on artstation, pixiv -phil noto, peter mohrbacher, thomas kinkade, artgerm, 1 9 5 0 s rockabilly anya taylor - joy catwoman dc comics, symmetrical eyes, city rooftop -dnd character concept portrait, angry male elf druid in forest, detailed, high quality, dynamic lighting, fantasy, artwork by artgerm, wlop, alex ross, greg rutknowski, alphonse mucha -a king with a skull head, in the style of artgerm, charlie bowater, atey ghailan and mike mignola, vibrant colors and hard shadows and strong rim light, plain background, comic cover art, trending on artstation -With the spikes in her hair -venus, the empress, wearing a magnificent dress, sitting on a divan in the middle of a beautiful green plains full of little flowers. intricate, elegant, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, by justin gerard and artgerm, 8 k -beautiful apocalyptic woman with pink Mohawk, standing on mad max panzer tank, 4k ultra hd, fantasy dark art, tank girl, artgerm, concept art, artstation, octane render, elegant, detailed digital painting -i crave only the cold clean certainty of steel and silicon, trending on artstation -nikola tesla, lightning, portrait, sharp focus, digital art, concept art, dynamic lighting, epic composition, colorful, trending on artstation, by emylie boivin 2. 0, rossdraws 2. 0 -professional concept art of a symmetrical ominous floating terrifying thing in a dark room by artgerm and greg rutkowski ( thin white border ). an intricate, elegant, highly detailed digital painting, concept art, smooth, sharp focus, illustration, in the style of cam sykes, wayne barlowe, igor kieryluk. -beautiful lifelike award winning marble statue bust of tsunku trending on art station artgerm greg rutkowski alphonse mucha museum quality cinematic atmospheric -steampunk robot ant, unreal engine realistic render, 8 k, micro detail, intricate, elegant, highly detailed, centered, digital painting, artstation, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, wlop, boris vallejo -mtg character portrait of a brawny male leonin warrior african lion angel of justice, with fiery golden wings of flame, wearing shining armor, wielding flaming sword and holding large fiery shield, by peter mohrbacher, wadim kashin, greg rutkowski, larry elmore, george pemba, ernie barnes, raymond swanland, magali villeneuve, trending on artstation -dynamic portrait painting of Michael Myers sitting in the waiting room of an optometrist amongst other normal patients, sharp focus, face focused, trending on ArtStation, masterpiece, by Greg Rutkowski, by Ross Tran, by Fenghua Zhong, octane, soft render, oil on canvas, moody lighting, high contrast, cinematic, professional environmental concept art -Concept art of male high elf with light blue hair, black leather armor, golden eagle skull on chest, by Naranbaatar Ganbold, trending on artstation -a closeup portrait of a mia khalifa, dramatic light, lake background, sunset, dark, painted by stanley lau, painted by greg rutkowski, painted by stanley artgerm, digital art, trending on artstation -portrait of salman rushdie, deep focus, d & d, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -anime key visual of beautiful elizabeth olsen police officer, cyberpunk, futuristic, stunning features, perfect face, high details, digital painting, artstation, smooth, soft focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -Beautiful portrait of an attractive Persian Princess who is an architect, beautiful princess, face painting, dramatic lighting, intricate, wild, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, footage from space camera -full body portrait character concept art, anime key visual of a little witch with her capybara mascot, trending on pixiv fanbox, painted by makoto shinkai takashi takeuchi studio ghibli -perfectly-centered-Portrait of the most beautiful people on the planet, river, washing clothes, intricate, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, Unreal Engine 5, 8K, art by artgerm and greg rutkowski and alphonse mucha -wide shot of vietnamese solider girl, green uniform, burning city in the background, epic, elder scrolls art, fantasy, skyrim, hd shot, digital portrait, beautiful, artstation, by artgerm, guy denning, jakub rozalski, magali villeneuve and charlie bowater -apocalyptic city, digital painting, artstation, concept art, donato giancola, Joseph Christian Leyendecker, WLOP, Boris Vallejo, Breathtaking, 8k resolution, extremely detailed, beautiful, establishing shot, artistic, hyperrealistic, octane render, cinematic lighting, dramatic lighting, masterpiece, light brazen -male dracula rollerskating with rollerskates in a roller rink by charlie bowater and titian and artgerm, full body portrait, intricate, face, elegant, beautiful, highly detailed, dramatic lighting, sharp focus, trending on artstation, artstationhd, artstationhq, unreal engine, 4 k, 8 k -a dark forest where gears and electronic parts grow on the trees tops, cyberpunk landscape wallpaper, d&d art, fantasy, painted, 4k, high detail, sharp focus -Photorealistic elvish goddess in a magical bioluminescent forest Hyperdetailed photorealism, 108 megapixels, amazing depth, glowing rich colors, powerful imagery, psychedelic Overtones, 3D finalrender, 3d shading, cinematic lighting, artstation concept art -portrait of a demon, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha and william - adolphe bouguereau -the man stuck in the wall, creepy explorer sketch, godlike design, concept art, beyond the void, grand scale, intricate detailed -Very very very very highly detailed epic central composition studio photography of face with venetian mask, intricate, dystopian, sci-fi, extremely detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, intimidating lighting, incredible art by Anna Dittmann and Jesper Ejsing and Anton Pieck -water, glowing lights!! intricate elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by greg rutkowski -highly detailed portrait of Eminem wearing a beret and gold chains and brandishing a pistol, big eyes, realistic portrait, symmetrical, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha -robocop torso, symmetry, faded colors, exotic alien features, cypherpunk background, tim hildebrandt, wayne barlowe, bruce pennington, donato giancola, larry elmore, masterpiece, trending on artstation, featured on pixiv, cinematic composition, beautiful lighting, sharp, details, hyper detailed, 8 k, unreal engine 5 -Boris Johnson as Neo from Matrix, black sunglasses, realistic portrait, symmetrical, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha -a copic maker sketch of a stewardess girl wearing kikyo's clothing designed by balenciaga by john berkey by stanley artgerm lau, greg rutkowski, thomas kinkade, alphonse mucha, loish, norman rockwell -a matte painting of a man sitting down and having a cup of tea in his house by the beach, in the style of artgerm, charlie bowater, atey ghailan and mike mignola, vibrant colors and hard shadows and strong rim light, plain background, comic cover art, trending on artstation -a smug exclusivists female, black ink line art and watercolor, intricate, digital painting, concept art, smooth, focus, rim light style tim burton -3 5 mm portrait of samurai in training dojo, in the style of david cronenberg, scary, weird, high fashion, id magazine, vogue magazine, surprising, freak show, realistic, sharp focus, 8 k high definition, film photography, photo realistic, insanely detailed, intricate, by david kostic and stanley lau and artgerm -rats fixing cars in the garage, key visual, a fantasy digital painting by makoto shinkai and james gurney, trending on artstation, highly detailed -photo of a gorgeous sultry young woman in the style of David la chapelle , realistic, sharp focus, 8k high definition, 35mm film photography, photo realistic, insanely detailed, intricate, elegant, art by David kostic and stanley lau and artgerm -sliced coconut, electronics, ai, cartoonish cute, pine trees, dramatic atmosphere, trending on artstation, 3 0 mm, by noah bradley trending on artstation, deviantart, high detail, stylized portrait -360 degree equirectangular, anthropomorphic family of mushrooms, family portrait, Art Deco nature, mystical fantasy, Pixar cute character design, intricate art deco mushroom patterns, elegant, sharp focus, 360 degree equirectangular panorama, art by Artgerm and beeple and Greg Rutkowski and WLOP, 360 monoscopic equirectangular -portrait of othinus from toaru, anime fantasy illustration by tomoyuki yamasaki, kyoto studio, madhouse, ufotable, trending on artstation -a portrait of a evil cybernetic magician in glass armor releasing spell, full height, moving forward, cyberpunk concept art, trending on artstation, highly detailed, intricate, sharp focus, digital art, 8 k -Portrait of the black dragon Alduin breathing a rainbow-colored fire. 4k. Concept art. High detail. Unreal engine. -Greg Manchess portrait painting of Ganon from Legend of Zelda as Overwatch character, medium shot, asymmetrical, profile picture, Organic Painting, sunny day, Matte Painting, bold shapes, hard edges, street art, trending on artstation, by Huang Guangjian and Gil Elvgren and Sachin Teng -a hyper - realistic character concept art portrait of emilia clarke, depth of field background, artstation, award - winning realistic sci - fi concept art by jim burns and greg rutkowski, beksinski, a realism masterpiece, james gilleard, bruegel, alphonse mucha, and yoshitaka amano. -Wide shot of a chrome spaceship in battle, explosions and purple lasers. Asteroid belt. Scenic view, in the void of space, underexposed, matte painting by Craig mullins and Emmanuel_Shiu and john berkey, cinematic, dark sci-fi, concept art trending on artstation, 4k, insane details, ultra realistic -ebony beauty portrait, black red smoke, ink, stylized tattoos, draconic priestess, portrait by Artgerm, peter mohrbacher -leonine devil in flowing robes, ethereal, backlit, high fantasy, highly detailed, puzzled expression, realistic lighting, sharp focus, intricate, by artgerm, wlop, crossdress, frank frazetta, trending on artstation -giant magical floating golden sun, bright godrays, vibrant colors, by sylvain sarrailh, rossdraws, ambient light, ultra detailed, fantasy artwork, 8 k, volumetric lighting, trending on artstation, award winning, beautiful scenery, very beautiful. -a 3 d render of a stack of green cubes on the left and an orange ball on the right in a red room, blender, ue 5, octane render, trending on artstation -ori and the olw, close up bokeh hiperrealistic, high detailled, darkness dramatic, sharp focus, octane render, imax -richly detailed color illustration of a fiending-addict-seeking-at-the-doctors-office illustrated by Artgerm and Mina Petrovic and Timothy Kong and Marina Federovna. 3D shadowing -a study of cell shaded portrait of Dora the Explorer as a Borderlands 3 character, llustration, post grunge, concept art by josan gonzales and wlop, by james jean, Victo ngai, David Rubín, Mike Mignola, Laurie Greasley, highly detailed, sharp focus, alien, Trending on Artstation, HQ, deviantart, art by artgem -A beautiful female warrior holding a bow an arrow wearing a magical bikini posing on a rock in a magical forest, super detailed and realistic face, fantasy art, in the style of Artgerm, illustration, epic, fantasy, intricate, hyper detailed, artstation, concept art, smooth, sharp focus, ray tracing, vibrant -Lofi Steampunk Bioshock portrait, Pixar style, by Tristan Eaton Stanley Artgerm and Tom Bagshaw -a beautiful hyperdetailed highly detailed urbex industrial architecture tower nature building unfinished building by zaha hadid, retro sunset retrowave darkacademia at fall hyperrealism cgsociety tokyo at night thermal vision, archdaily, wallpaper, highly detailed, trending on artstation. -Cyborg woman sitting on a chair in a futuristic room smoking a cigar, intricate, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, Unreal Engine 5, 8K, art by artgerm and greg rutkowski and alphonse mucha -young angry woman, beautiful girl, full body, explosive hair, cowboy hat, realistic, serov, surikov, vasnetsov, repin, kramskoi, insanely detailed, charlie bowater, tom bagshaw, high resolution, octane rendered, unreal engine, illustration, trending on artstation, masterpiece, 8 k -an anime landscape of a girl wearing a kimono, near the river in a japanese summer festival from skyrim, by stanley artgerm lau, wlop, rossdraws, james jean, andrei riabovitchev, marc simonetti, and sakimichan, trending on artstation -highly detailed portrait of a man with a handsaw head by greg rutkowski and fujimoto tatsuki, dramatic lighting, dynamic pose, dynamic perspective -film noir woman, character sheet, concept design, contrast, hot toys, kim jung gi, greg rutkowski, zabrocki, karlkka, jayison devadas, trending on artstation, 8 k, ultra wide angle, pincushion lens effect -portrait of a diabolical marble stone cyborg, wearing torn white cape, dynamic pose, glowing eyes, post apocalyptic ancient ruins, glowing veins subsurface scattering, in clouds, sunset, portrait, by gerald brom, by mikhail vrubel, by peter elson, muted colors, extreme detail, trending on artstation, 8 k -portrait of donald trump, soft hair, muscular, half body, leather, hairy, d & d, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -black super hero girl | very very anime!!!, fine - face, beyonce, realistic shaded perfect face, fine details. anime. realistic shaded lighting poster by ilya kuvshinov katsuhiro otomo ghost - in - the - shell, magali villeneuve, artgerm, jeremy lipkin and michael garmash and rob rey -richly detailed color illustration of a nerd-core-instructional-video illustrated by Artgerm and Mina Petrovic and Timothy Kong and Marina Federovna. 3D shadowing -a group of spanish trap singers drinking red wine, oil painting by alex katz, trending on artstation -photorealistic beautiful ethereal natalie portman in the style of michael whelan and greg rutkowski. hyperdetailed photorealism, 1 0 8 megapixels, amazing depth, glowing rich colors, powerful imagery, psychedelic overtones, 3 d finalrender, 3 d shading, cinematic lighting, artstation concept art -a cute pet by neville page, ken barthelmey, carlos huante and doug chiang, sharp focus, trending on artstation, hyper realism, octane render, 8 k, hyper detailed, ultra detailed, highly detailed, zbrush, concept art, creature design -very cute illustration for a children's book, digital art, detailed, rim light, exquisite lighting, clear focus, very coherent, details visible, soft lighting, character design, concept, atmospheric, dystopian, trending on artstation, fog, sun flare -Still of a humanoid robot painting on a canvas, high detail, cinematic, , science fiction concept art by Greg Rutkowski and Moebius and Le Corbusier -asymmetrical!! long shot of a snufkin smoking a pipe, nebula, intricate, elegant, highly detailed, digital painting, artstation, biolusence, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, horizon zero dawn 8 k -portrait of red - tinged, red leds, futuristic cybernetic warrior alien in profile, highly intricate, detailed humanoid, trending on artstation -of a beautiful scary Hyperrealistic stone castle on top of a hill in the middle of a dark and creepy forest, macro lens, highly detailed, digital painting, trending artstation, concept art, illustration, cinematic lighting, vibrant colors, photorealism, epic, octane render -piles of modular synth cables mixed with mangrove roots mixed with old video game consoles, puerto rican grafitti goddess chilling out wearing a headpiece made of circuit boards, by cameron gray, wlop, stanley kubrick, masamune, unique perspective, epic, trending on artstation, photorealistic, 3 d render, vivid -oil painting portrait of a young woman with long flowing hair in a white dress, dancing through a field of flowers at sunset with mountains in the background, hazy, digital art, chiaroscuro, artstation, cinematic, golden hour, digital art painting by greg rutkowski, william - adolphe bouguereau, hazy atmosphere, flowers, cinematic lighting -dark wizard of forest, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -photorealistic dog piloting a biplane. hyperdetailed photorealism, 1 0 8 megapixels, amazing depth, glowing rich colors, powerful imagery, psychedelic overtones, 3 d finalrender, 3 d shading, cinematic lighting, artstation concept art -clear portrait of tony soprano, cottagecore!!, mafia background hyper detailed, character concept, full body, dynamic pose, intricate, criminal appearance, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -fantasy art of glowing goldfish swimming in the air, in the streets of a japanese town at night, with people watching in wonder, by fenghua zhong, highly detailed digital art, trending on artstation -fantasy steps with pillars on both sides by greg rutkowski -award winning digital portrait of a feminine attractive male jester at a magnificent circus, beautiful circus themed background with soft colors and lights, trending artstation, digital art, aesthetic, bloom, intricate, elegant, sharp focus, digital illustration, highly detailed, octane render, digital painting, concept art, fantasy, masterpiece, by lisa buijteweg and sakimichan -a ultradetailed beautiful concept art of an old mind key, with intricate detail, oil panting, high resolution concept art, 4 k, by artgerm -Ogun with large iron spears, he has tribal face markings and war paint, bronze-brown skin with african features and strong jaw line prominent brow and menacing look, wearing tribal armor, medium shot digital illustration trending on artstation by artgerm, face by wlop -full face shot of rimuru tempest, sky blue straight hair, long bangs, with amber eyes, gold eyes, wearing a black jacket, high collar, ultra detailed, concept art, award winning photography, digital painting, cinematic, wlop artstation, closeup, pixiv, evil, yoshitaka amano, andy warhol, ilya kuvshinov, -Moon Knight mixed with Goku, RPG Reference, art by ilya kuvshinov, artgerm, Alphonse mucha, and Greg Rutkowski, Trending on Artstation, octane render, Insanely Detailed, 8k, HD -portrait of the cutest red fox ever, fluffy, cinematic view, epic sky, detailed, concept art, low angle, high detail, warm lighting, volumetric, godrays, vivid, beautiful, trending on artstation, by jordan grimmer, huge scene, grass, art greg rutkowski -bandit, ultra detailed fantasy, elden ring, realistic, dnd, rpg, lotr game design fanart by concept art, behance hd, artstation, deviantart, global illumination radiating a glowing aura global illumination ray tracing hdr render in unreal engine 5 -ilya kuvshinov with blue hair, yellow irises, professional digital painting, concept art, unreal engine 5, 8 k, cinematic, wlop, tendrils in the background, art by greg rutkowski, pixiv art, junji ito, yoshitaka amano -high resolution concept art of naruto and yoda kissing in paris -character concept portrait of a stoic and proud woman in an elegant gown, pale face, intricate, elegant, digital painting, concept art, smooth, sharp focus, illustration, from Metal Gear, by Ruan Jia and Mandy Jurgens and William-Adolphe Bouguereau, Artgerm -symmetry!! portrait of skull, sci - fi, glowing lights!! intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, 8 k -realistic portrait of beautifully crystalized and detailed portrait of a biomech zombie woman wearing a gasmask, matte painting of cinematic movie scene red dragon, horror, created by gustave dore and greg rutkowski, high detailed, smooth draw, synthwave neon retro, intricate, realistic proportions, dramatic lighting, trending on artstation. -a portrait of sexy lady casting ice - ball and shoot it, cyberpunk concept art, trending on artstation, highly detailed, intricate, sharp focus, digital art, 8 k -close up shot of a full body floating astronaut portrait smoke elemental fading into white smoke, high contrast, james gurney, peter mohrbacher, mike mignola, black paper, mandelbulb fractal, trending on artstation, exquisite detail perfect, large brush strokes, bold pinks and blues tones, intricate ink illustration, black background -beautiful blonde teenage boy assassin, wearing leather jacket, beautiful, detailed portrait, cell shaded, 4 k, concept art, by wlop, ilya kuvshinov, artgerm, krenz cushart, greg rutkowski, pixiv. cinematic dramatic atmosphere, sharp focus, volumetric lighting, cinematic lighting, studio quality -commission of a robot chasing thugs.dramatic,character design by charles bowater,greg rutkowski,ross tran,hyperdetailed,hyperrealistic,4k,deviantart,artstation,professional photography,concept art,dramatic -foggy neon night, sayaka isoyama leaning back against a wall in a black minidress smoking a cigarette outside a neon lit entrance, 1 9 7 0 s, intricate, moody, tasteful, intimate, highly detailed, short focus depth, artgerm, donato giancola, joseph christian leyendecker -concept art of a shalltear bloodfallen and vladimir volegov and alexander averin and delphin enjolras and daniel f. gerhartz -of a dark and stormy ocean with large strange cute water creatures with big eyes, mouth and round teeth appearing from the water, in the style of Gaudi, macro lens, shallow depth of field, highly detailed, digital painting, trending artstation, concept art, illustration, cinematic lighting, vibrant colors, photorealism, epic, octane render -cat with lute, sitting in the rose garden, medieval portrait, concept art, close up -harry styles as miley cyrus riding a wrecking ball, high octane render, digital art trending on artstation -loch ness monster by charlie bowater and titian and artgerm, full - body portrait, intricate, face, lake, elegant, green mist, beautiful, highly detailed, dramatic lighting, sharp focus, trending on artstation, artstationhd, artstationhq, unreal engine, 4 k, 8 k -a full body portrait of a young latin woman in a flowery fruit - based dress, with a greek mask on her head, night lighting with candles delicate features finely detailed perfect art, at an ancient city, gapmoe yandere grimdark, trending on pixiv fanbox, painted by greg rutkowski makoto shinkai takashi takeuchi studio ghibli -ultra realistic illustration, young man with dark gray skin, short white hair, intricate, with dark clothes, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -concept art by jama jurabaev, cel shaded, cinematic shot, trending on artstation, high quality, brush stroke, hyperspace, vibrant colors, portrait of rick grimes -a beautiful portrait of a pearl goddess with glittering skin, a detailed painting by greg rutkowski and raymond swanland, featured on cgsociety, fantasy art, detailed painting, artstation hd, photorealistic -of a advertisement with a scene of a highway with words written on the road in front of the viewer, occlusion shadow, specular reflection, rim light, unreal engine, octane render, artgerm, artstation, art jiro matsumoto, high quality, intricate detailed 8 k, sunny day -best book cover design, glowing silver and golden elements, full close-up portrait of realistic crow with gems, book cover, green forest, white moon, establishing shot, extremly high detail, photo-realistic, cinematic lighting, by Yoshitaka Amano, Ruan Jia, Kentaro Miura, Artgerm, post processed, concept art, artstation, matte painting, style by eddie mendoza, raphael lacoste, alex ross -a girl is running, sport clothing, fitness watch, anime style, brown short hair, hair down, symmetrical facial features, from arknights, hyper realistic, rule of thirds, extreme detail, 4 k drawing, trending pixiv, realistic lighting, by alphonse mucha, greg rutkowski, sharp focus, backlit -a hyper realistic professional photographic picture of dragon hotdog, photographic filter unreal engine 5 realistic hyperdetailed 8k ultradetail cinematic concept art volumetric lighting, digital artwork, very beautiful scenery, very realistic painting effect, hd, hdr, cinematic 4k wallpaper, 8k, ultra detailed, high resolution -A portrait of a male elf, 20 years old, short silver hair, red eyes, wearing a spiked black metal crown, black heavy armor with gold trim, and a red cape, lean but muscular, attractive, command presence, royalty, weathered face, smooth, sharp focus, illustration, concept art, highly detailed portrait muscle definition, fantasy painting, ArtStation, ArtStation HQ -2 8 mm macro headshot of a ethereal magical young winged fairy princess wearing a white robe in a fantasy garden, d & d, fantasy, intricate, rim light, god rays, volumetric lighting, dark souls, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, orthodoxy, art by greg rutkowski, maxfield parrish and alphonse mucha, new art nouveau, soft lighting, tarot card -portrait of sansa stark with crown, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha and william - adolphe bouguereau -lush solarpunk Victorian windowsill with futuristic plants on it, looking out toward a solarpunk cityscape, vignette of windowsill, detailed digital concept art by anton fadeev and marc simonetti, trending on artstation -a portrait of a beautiful biomechanical queen of necropolis, horror concept art by giger and beksinski and szukalski and wlop and pete mohrbacher, digital art, highly detailed, intricate, sci-fi, sharp focus, Trending on Artstation HQ, deviantart, unreal engine 5, 4K UHD image -ocean of canvas that catches liquid fire, intricate pearls, ornate ruby, magical, concept art, art nouveau, Reylia Slaby, Peter Gric, trending on artstation, volumetric lighting, CGsociety -incredible, refugees crossing a mindblowingly beautiful bridge made of rainbow, energy pulsing, hardlight, matte painting, artstation, solarpunk metropolis, cgsociety, dramatic lighting, vibrant greenery, concept art, octane render, arnold 3 d render -bemused to be soon consumed by a tentacle demon, in a leather neck restraint, beautiful young woman with medium length silky black hair in a black silk tank top in a full frame zoom up of her face and neck in complete focus, looking upwards in a room of old ticking clocks, complex artistic color ink pen sketch illustration, subtle detailing, gentle shadowing, fully immersive reflections in her eyes, concept art by Artgerm and Range Murata in collaboration. -baby yoda, portrait, concept art by doug chiang cinematic, realistic painting, high definition, concept art, portait image, path tracing, serene landscape, high quality, highly detailed, 8 k, soft colors, warm colors, turbulent sea, high coherence, anatomically correct, hyperrealistic, concept art, defined face, symmetrical 5 -isometric 3D of the ethereum symbol in gold and black by artgerm and greg rutkowski, alphonse mucha, cgsociety and beeple highly detailed, sharp focus, cinematic lighting, illustration, art, octane render, Unreal Engine Lumen, very coherent. cinematic, hyper realism, high detail, octane render, 8k -giant snake on a moonlit desert, fantasy, d & d, art by artgerm and greg rutkowski, cinematic shot, intricate, ornate, photorealistic, ultra detailed, trending artstaition, realistic, 1 0 0 mm, photography, octane, high definition, depth of field, bokeh, 8 k -a beautiful portrait of a skull goddess by Greg Rutkowski and Raymond Swanland, Trending on Artstation, ultra realistic digital art -a whirlwind of souls rushing inside the metaverse, half body, glowin eyes, insect, lizard, d & d, fantasy, intricate, elegant, highly detailed, colorful, vivid color, digital painting, artstation, concept art, art by artgerm and greg rutkowski and alphonse mucha and ruan jia -medieval knight power armour, 4 0 k, space marine, concept art, medieval, fantasy, cinematic lighting, detailed digital matte painting in the style of simon stalenhag and bev dolittle zdzislaw beksinski, greg hildebrandt artstation -portrait of burning woman, fire, blood red eyes, open mouth, vampire fangs, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, octane render, unreal engine, art by aenaluck and roberto ferri and greg rutkowski, epic fantasy, digital painting -portrait of a beautiful mysterious woman warrior wearing an armour costume, holding a bouquet of flowing flowers, hands hidden under the bouquet, fantasy, regal, intricate, by stanley artgerm lau, greg rutkowski, thomas kinkade, alphonse mucha, loish, norman rockwell -a wholesome animation key shot of a band behemoth performing on stage, medium shot, studio ghibli, pixar and disney animation, 3 d, sharp, rendered in unreal engine 5, anime key art by greg rutkowski, bloom, dramatic lighting -dungeons and dragons old evil wizard character closeup portrait, dramatic light, lake background, 2 0 0 mm focal length, painted by stanley lau, painted by greg rutkowski, painted by stanley artgerm, digital art, trending on artstation -scenery from game of thrones, wide angle, super highly detailed, professional digital painting, artstation, concept art, smooth, sharp focus, no blur, no dof, extreme illustration, unreal engine 5, photorealism, hd quality, 8 k resolution, cinema 4 d, 3 d, beautiful, cinematic, art by artgerm and greg rutkowski and alphonse mucha and loish and wlop -female elf bard, Jade, dungeons and dragons, amazing detail, character concept art, illustration, fantasy, 4k -detailed coffee table in the vaporwave mid century modern livingroom. highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, wlop, boris vallejo -retrofuturistic portrait of a uyghur prisoner in a tracksuit that's dirty and ripped, close up, wlop, dan mumford, artgerm, liam brazier, peter mohrbacher, jia zhangke, 8 k, raw, featured in artstation, octane render, cinematic, elegant, intricate, 8 k -3 / 4 view of a portrait of pixie woman with bat wings, confident pose, pixie, genshin impact,, intricate, elegant, sharp focus, illustration, highly detailed, concept art, matte, trending on artstation, anime, art by wlop and artgerm and greg rutkowski, strong brush stroke, sharp focus, illustration, morandi color scheme, art station, by ilya kuvshinov h 6 4 0 -high angle photo of a gorgeous big chungus in the style of stefan kostic, realistic, sharp focus, 8 k high definition, insanely detailed, intricate, elegant, art by stanley lau and artgerm -A highly detailed matte oil painting of a forest by Mokoto Shinkai, hyperrealistic, breathtaking, beautiful composition, by Artgerm, by beeple, by Studio Ghibli, cinematic lighting, octane render, 4K resolution, trending on artstation -realistic detailed image of a dark figure screaming on a wooden cross in the middle of a busy city street in the style of francis bacon, hooded figure surreal, norman rockwell and james jean, greg hildebrandt, and mark brooks, triadic color scheme, by greg rutkowski, in the style of francis bacon and syd mead and edward hopper and norman rockwell and beksinski, dark surrealism, open ceiling, highly detailed, painted by francis bacon, painted by james gilleard, surrealism, by nicola samori, airbrush, ilya kuvshinov, wlop, stanley artgerm, very coherent, art by takato yamamoto and james jean -a photorealistic dramatic hyperrealistic render of a beautiful mazinger z by go nagai, wlop, greg rutkowski, alphonse mucha, beautiful dynamic dramatic dark moody lighting, shadows, cinematic atmosphere, artstation, concept design art, octane render, 8 k -a portrait of the most beautiful woman in the world with long black hair that extends past her waist with locks of hair that frame her face down to her chin and shows off her high forehead, dark brown eyes with long, voluminous eyelashes and pale skin, narrow waist and very large chest, wearing a revealing red V-neck blouse a loose sarong with the green symbol of the Kuja adorned on it, along with a white cape sporting epaulettes more commonly found on the jackets of high-ranking Marines, and red high heel pumps, pink hearts in the background , romantic themed, beautiful face, intricate, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration -portrait of melted zeus starring into the camera, fixed eyes, lightning environment, surreal, dramatic lighting, face, detailed, intricate, elegant, highly detailed, digital painting, artstation,, concept art, smooth, sharp focus, illustration, art by sam spratt, dan mumford, artem demura and alphonse mucha -portrait painting of a punk elven bard with green eyes and snow white fur, ultra realistic, concept art, intricate details, eerie, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and charlie bowater and magali villeneuve and alphonse mucha -gigachad jill valentine bodybuilder jumping from a building fighting in racoon city, fantasy character portrait, ultra realistic, anime key visual, full body concept art, intricate details, highly detailed by greg rutkowski, ilya kuvshinov, gaston bussiere, craig mullins, simon bisley -inside a medieval hobbit home, ornate, beautiful, atmosphere, vibe, mist, smoke, chimney, rain, well, wet, pristine, puddles, red speckled mushrooms, waterfall, melting, dripping, snow, creek, lush, ice, bridge, cart, bonzai, green, stained glass, forest, flowers, concept art illustration, color page, 4 k, tone mapping, doll, akihiko yoshida, james jean, andrei riabovitchev, marc simonetti, yoshitaka amano, digital illustration, greg rutowski, volumetric lighting, sunbeams, particles, trending on artstation -girl with super long hair, hair becoming autumn red leaves, intricate, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -a phantom undead mage ape with whirling galaxy around, tattoos by anton pieck, intricate, extremely detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, intimidating lighting, incredible art, -a stunningly detailed picture of indoor botanical garden , girl, by greg rutkowski and thomas kinkade, trending on artstation -death is swallowed up in victory, very detailed and beautiful portrait of a young woman by daniel oldenburg, necromancer bt h. r. giger, screaming with fear, artwork by artgerm, centered shot, wide angle, full body, islandpunk, solarpunk, fantasy, highly detailed, digital painting, artstation, smooth, sharp focus, landscape art by thomas kinkade and yusei uesugi -a painting of the most beautiful spaceship, an exquisite and beautiful rendition, by greg rutkowski -3d infrared octane render concept art by Mo Xiang Tong Xiu, by Igarashi Daisuke, by makoto shinkai, cute beauty cozy portrait anime sad schoolgirls under dark pink and blue tones, mirror room. light rays. deep water bellow. realistic 3d face. dramatic deep light, trending on artstation, oil painting brush -anthropomorphic art of a timelord owl inside tardis, victorian inspired clothing by artgerm, victo ngai, ryohei hase, artstation. fractal papersand books. highly detailed digital painting, smooth, global illumination, fantasy art by greg rutkowsky, karl spitzweg, doctor who -otters playing poker, hyper detailed, dramatic lighting, cgsociety, realistic, hyper detailed, insane details, intricate, dramatic lighting, hypermaximalist, golden ratio, rule of thirds, octane render, weta digital, micro details, ultra wide angle, artstation trending, 8 k, -hieronymus bosch, greg rutkowski, anna podedworna, painting of chris farley in his academy award winning role -baroque rococo futuristic aristocrat, d & d, fantasy, portrait, highly detailed, digital painting, trending on artstation, concept art, sharp focus, illustration, art by artgerm and greg rutkowski and magali villeneuve -full body pose, hyperrealistic photograph of inner peace, dim volumetric lighting, 8 k, octane beautifully detailed render, extremely hyper detailed, intricate, epic composition, cinematic lighting, masterpiece, trending on artstation, very very detailed, stunning, hdr, smooth, sharp focus, high resolution, award, winning photo, dslr, 5 0 mm -painting of hybrid hamster and gecko!!!!, intercrossed animal, crossbred, by zdzislaw beksinski, by lewis jones, cold hue's, warm tone gradient background, concept art, digital painting -Given,' Fivetide said, nodding his eye stalks, re-winding his harpoon cable, lifting a piece of meat from his own plate to his beak, reaching for a drink and drumming one tentacle on the table with everybody else as one of the scratchounds got another on its back and bit its neck out. 'Good play! Good play! Seven; that's my dog! Mine; I bet on that! I did! Me! You see, Gastrees? I told you! Ha ha ha! Sci-fi, sunrise, concept art, octane render, unreal engine 5, trending on Artstation, high quality, highly detailed, 8K, soft lighting, godrays, path tracing, serene landscape, turbulent sea, high coherence, anatomically correct, hyperrealistic, sand, beautiful landscape, cinematic, -fantasy art of a bustling tavern in china, at night, by fenghua zhong, highly detailed digital art, trending on artstation -portrait painting of elizabeth olsen wanda maximoff with green skin and pointy ears wearing sci - fi clothes, ultra realistic, concept art, intricate details, eerie, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and charlie bowater and magali villeneuve and alphonse mucha -a portrait of tony stark, fantasy, sharp focus, intricate, elegant, digital painting, artstation, matte, highly detailed, concept art, illustration, ambient lighting, art by ilya kuvshinov, artgerm, alphonse mucha, and greg rutkowski -portrait of the two most beautiful women surrounded by soft florals, vaporwave lighting, dewy skin, concept art, high detail, beautiful, dreamy -a beautiful portrait painting of a ( ( cyberpunk ) ) girl by simon stalenhag and pascal blanche! and alphonse mucha! and nekro!!. in style of digital art. colorful comic, film noirs!, symmetry, hyper detailed. octane render. trending on artstation -emma thompson as an angel standing in the front of gates of hell. angel is draped with bones. digital painting. art station. mood lighting. skindness, highly detailed, concept art, intricate, sharp focus, einar jonsson and bouguereau - h 1 2 0 0 -tyrion lannister working in a winery, animation pixar style, by magali villeneuve, artgerm, jeremy lipkin and michael garmash, rob rey and kentaro miura style, golden ratio, trending on art station -a dramatic, epic, ethereal painting of a !handsome! (very thicc) mischievous shirtless cowboy with a beer belly wearing a large belt and bandana offering a whiskey bottle | he is relaxing by a campfire | background is a late night with food and jugs of whisky | homoerotic | stars, tarot card, art deco, art nouveau, mosaic, intricate | by Mark Maggiori (((and Alphonse Mucha))) | trending on artstation -anime character portrait of a female martial artist!! elegant, intricate outfit, fine details by stanley artgerm lau, wlop, rossdraws, james jean, andrei riabovitchev, marc simonetti, and sakimichan, trembling on artstation -portrait of green anthropomorphic mantis religiosa ; hard predatory look ; d & d rogue ; powerful front forelegs holding an enchanted dagger ; flat triangle - shaped head with antennae and compound eyes ; concept art ; artstation ; 8 k ; wallpapers ; heavy contrast ; cinematic art ; cgsociety ; high coherence ; golden ratio ; rule of thirds ; art by greg rutkowski and artgerm -close up Portrait of elizabeth olsen as real life beautiful young teen girl wearing assamese bihu mekhela sleeveless silk saree and gamosa in Assam tea garden, XF IQ4, 150MP, 50mm, F1.4, ISO 1000, 1/250s, attractive female glamour fashion supermodel photography by Steve McCurry in the style of Annie Leibovitz, face by Artgerm, daz studio genesis iray, artgerm, mucha, bouguereau, gorgeous, detailed anatomically correct face!! anatomically correct hands!! amazing natural skin tone, 4k textures, soft cinematic light, Adobe Lightroom, photolab, HDR, intricate, elegant, highly detailed,sharp focus -digital character concept art by artgerm and greg rutkowski and alphonse mucha. clear portrait of a young wife blessed by god to uncontrollably become overwhelmingly perfect!! blonde, clothed! obviously feminine holy body!! light effect. hyper detailed, glowing lights!! intricate, elegant, digital painting, artstation, smooth, sharp focus -Gandalf, 4k oil on linen by wlop, artgerm, andrei riabovitchev, nuri iyem, james gurney, james jean, greg rutkowski, highly detailed, soft lighting 8k resolution -Cyborg biomechanical jellyfish deity, sci-fi, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -man male demon, full body white purple cloak, warlock, character concept art, costume design, illustration, black eyes, white horns, trending on artstation, Artgerm -baroque bedazzled gothic royalty frames surrounding a pixelsort rimuru tempest smiling, sky blue straight hair, bangs, with amber eyes, yellow golden eyes, wearing a black maximalist spiked jacket, high collar, ultra detailed, concept art, digital painting, pretty, cinematic, wlop artstationin wonderland, sharpened early computer graphics, remastered chromatic aberration -close up portrait of a ghost in the mountains of hell, oil painting by tomasz jedruszek, cinematic lighting, pen and ink, intricate line, hd, 4 k, million of likes, trending on artstation -A Snowplow clearing a beautiful snowy landscape with a small hut in the background. A blizzard and heavy snow falls. Fog and mist, highly detailed, concept art, digital art, 4k -closeup portrait shot of a cyberpunk child in a scenic dystopian environment, intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, wlop, boris vallejo -portrait of a girl by ayami kojima, mixture between russian and japanese, she is about 2 0 years old, black bob hair, very tall and slender, she is wearing a steampunk tactical gear, highly detailed portrait, digital painting, artstation, concept art, smooth, sharp foccus ilustration, artstation hq -a humanoid cello warrior, Character design, concept art -astronaut holding a flag in an underwater desert. a submarine is visible in the distance. dark, concept art, cinematic, dramatic, atmospheric, 8 k, trending on artstation, blue, fish, low visibility, light rays, extremely coherent, bubbles, fog, ocean floor, christopher nolan, interstellar, finding nemo -engine room on a starship,, star - field and planet in the background, digital art, highly detailed, trending on artstation, sci - fi -a portrait of a beautiful bikini model, art by lois van baarle and loish and ross tran and rossdraws and sam yang and samdoesarts and artgerm, digital art, highly detailed, intricate, sharp focus, Trending on Artstation HQ, deviantart, unreal engine 5, 4K UHD image -concept art oil painting by Jama Jurabaev, extremely detailed, brush hard, artstation, for AAA game, high quality -grey wizard casting a spell, details face, photo, bloody eyes, unreal engine, by popular digital artist, digital, artstation, detailed body, heavenly atmosphere, digital art, overdetailed art, trending on artstation, cgstudio, the most beautiful image ever created, dramatic, award winning artwork, beautiful scenery -schoolgirl with blonde twintails | very very anime!!!, fine - face, audrey plaza, realistic shaded perfect face, fine details. anime. realistic shaded lighting poster by ilya kuvshinov katsuhiro otomo ghost - in - the - shell, magali villeneuve, artgerm, jeremy lipkin and michael garmash and rob rey -kate beckinsdale comic cover art, artgerm, joshua middleton, pretty stella maeve witch doing black magic, serious look, purple dress, symmetrical eyes, symmetrical face, long black hair, full body, twisted evil dark forest in the background, cool colors -portrait painting of an elven galadrial beautiful women with dark shiny moon hair and gold sigils and thin arcane glyph's tattooed on her cheekbone, ultra realistic, concept art, intricate details, eerie, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and charlie bowater and magali villeneuve and alphonse mucha -portrait painting of an elven eladrin young man with short light orange hair and freckles and tribal tattoos on his cheekbones wearing fur armor, ultra realistic, concept art, intricate details, eerie, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and charlie bowater and magali villeneuve and alphonse mucha -portrait of kim wexler and saul goodman from better call saul. colourful suit, garish tie. oil painting elegant, highly detailed, centered, digital painting, artstation, concept art, hyperrealistic, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, ilya repin, drew struzan -old arnold schwarzenegger as a roman gladiator, fantasy, intricate, artstation, full body, concept art, smooth, sharp focus by huang guangjian and gil elvgren and sachin teng, 8 k -special forces soldier with ukrainian blue yellow flag standing alone on a huge pile of human skulls as a winner, masculine figure, d & d, fantasy, bright atmosphere, volumetric lights, intricate, elegant, extremely detailed, digital painting, artstation, concept art, matte, smooth, sharp focus, hyper realistic, illustration, art by artgerm and greg rutkowski and alphonse mucha -hyperrealistic document archive in a bunker, very detailed, technology, cyberpunk, dark blue and pink volumetric light, cgsociety, in the style of artgerm and artstation -a Photorealistic hyperrealistic render of an interior of a beautifully decorated spoiled child's beautiful bedroom, Close up low angle view of a vintage wind up toy robot on the floor with a giant teddy bear sitting on the bed by PIXAR,Greg Rutkowski,WLOP,Artgerm,dramatic moody sunset lighting,long shadows,Volumetric, cinematic atmosphere, Octane Render,Artstation,8k -Hyper realistic painting of a knight in rusty full plate armor wielding a greatsword, hyper detailed, surrounded by a dark forest, fog, moody, cinematic lighting, dim blue lighting, by greg rutkowski, trending on artstation -concept art, intricate vibrant colors,, cinematic shot, oil painting by jama jurabaev, extremely detailed, brush hard, artstation, for aaa game, high quality, brush stroke -teen girl, braided pink hair, gorgeous, amazing, elegant, intricate, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, art by Ross tran -a woman standing in a kitchen next to a plant that contains a small and thriving city, a storybook illustration by kiyohara tama, pixiv contest winner, magic realism, pixiv, official art, anime aesthetic -A medium shot anime portrait of a happy anime man with extremely short walnut hair, grey-blue eyes, wearing a t-shirt, his whole head fits in the frame, solid background, head shot, by Stanley Artgerm Lau, WLOP, Rossdraws, James Jean, Andrei Riabovitchev, Marc Simonetti, and Sakimi chan, trending on artstation -portrait painting of a post apocalyptic man, bald, black beard, handsome, ultra realistic, concept art, intricate details, eerie, highly detailed, fallout, wasteland, photorealistic, octane render, 8 k, unreal engine 5. art by artgerm and greg rutkowski and alphonse mucha -white anthropomorphic female vulpes vulpes fulva, smoking a cigarette in the rain, in crowded and wet street of a city, cyberpunk, harsh neon lights, highly detailed, digital painting, trending on artstation, concept art, sharp focus, illustration, art by artgerm and greg rutkowski and magali villeneuve -full body picture of a huntress lost in the futuristic maze, tired, beautiful and aesthetic, intricate, unreal engine, messy hair, highly detailed, detailed face, smooth, sharp focus, chiaroscuro, manga illustration, artgerm, greg rutkowski, ilya kuvshinov, rossdraws, alphonse mucha, young adult light novel cover art -a tree growing on a scrap car in ancient greek ruins, gray wasteland, many scrap cars, overgrown, pillars and arches, vines, hyperrealistic, highly detailed, cinematic, ray of golden sunlight, beautiful, cgsociety, artstation, 8 k, oil painting by greg rutkowski, by artgerm, by wlop -a skull alien chase a girl on alien planet by karol bak, james jean, tom bagshaw, rococo, sharp focus, trending on artstation, cinematic lighting, hyper realism, octane render, 8 k, hyper detailed, vivid, ultra detailed, highly detailed -detailed science - fiction character portrait of a sloth rock climbing, wild, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -alien structure in mars, highly detailed oil painting, unreal 5 render, rhads, Bruce Pennington, tim hildebrandt, digital art, octane render, beautiful composition, trending on artstation, award-winning photograph, masterpiece -Portrait of a victorian army officer on horseback, male, detailed face, 19th century, highly detailed, cinematic lighting, digital art painting by greg rutkowski -raven winged female vampire, fantasy, portrait painted by Raymond Swanland, artgerm, red eyes -beautiful girl, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, beautiful face, beautilful eyes, illustration, art by artgerm and greg rutkowski and alphonse mucha -hyperrealistic sculpture of a bronze fossilized moss tortoise dusted with iridescent spraypaint in a grid cage on a pedestal by ron mueck and duane hanson and lee bontecou, hyperrealistic dramatic colored lighting trending on artstation 8 k -an epic landscape view of a high - rise city on mars, with glowing lights at night, painted by tyler edlin, close - up, low angle, wide angle, atmospheric, volumetric lighting, cinematic concept art, very realistic, highly detailed digital art -tabletop game board, highly detailed, fantasy art, in the style of greg rutkowski, epic, fantasy, intricate, hyper detailed, artstation, concept art, smooth, sharp focus, ray tracing, top view -robotic arm with a laser rifle attached to it, realistic, 8 k, extremely detailed, cgi, trending on artstation, hyper - realistic render, 4 k hd wallpaper, premium prints available, by greg rutkowski -symmetry!! portrait of phoebe tonkin, machine parts embedded into face, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, 8 k -full body portrait of a woman posing, short wavy hair, round face, cottagecore!!, inside water, intricate, enlightened, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -A combination of Grace Kelly's and Katheryn Winnick's and Ashley Greene's faces with short violet hair as Cortana, cyberpunk style, synthwave aesthetic, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, half body portrait, anime style, art by Artgerm and Greg Rutkowski and Alphonse Mucha -hyperrealistic portrait of a woman monster astronaut, full body portrait, well lit, intricate abstract. cyberpunk, intricate artwork, by Tooth Wu, wlop, beeple. octane render,in the style of Jin Kagetsu, James Jean and wlop, highly detailed, sharp focus, intricate concept art, digital painting, ambient lighting, 4k, artstation -concept art of a mushroom creature, wearing tight clothes made of rocks, sitting on a rock in a cave | | cute - fine - fine details by stanley artgerm lau, wlop, rossdraws, and sakimichan, trending on artstation, brush strokes -closeup portrait shot of a victorian bottle of whiskey in a scenic mystery environment, intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, wlop, boris vallejo -bob odenkirk with reptile eyes, chrome metal shiny skin. intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, wlop, frank frazetta -portrait painting of a celtic female warrior with brown eyes and snow white fur, ultra realistic, concept art, intricate details, eerie, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and charlie bowater and magali villeneuve and alphonse mucha -David Ligare, wide angle scifi landscape, hyperrealistic surrealism, award winning masterpiece with incredible details, epic stunning, infinity pool, a surreal vaporwave liminal space, highly detailed, trending on ArtStation, artgerm and greg rutkowski and alphonse mucha, daily deviation, IAMAG, broken giant marble head statue ruins, golden hour -elon musk as bane from batman, realistic portrait, symmetrical, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha -a full body shot of a imposing cyborg ( bull ) modeled after a bull with open eyes looking into the camera, hard rubber chest, intricate pattern, highly detailed, android, cyborg, full body shot, intricate, 3 d, hyper realism, symmetrical, octane render, strong bokeh, fantasy, highly detailed, depth of field, digital art, artstation, concept art, cinematic lighting, trending -sheep, realistic portrait, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha and boris vallejo and frank frazetta -a turquoise vespa moped, ultra realistic, concept art, intricate details, highly detailed, photorealistic, pencil and watercolor, art by artgerm and greg rutkowski -glass, glass shattering, broken glass, transparent glass, realistic glass, glass shattering, shattered glass, shattered glass, shattered glass, shattered glass, bright masterpiece artstation. 8 k, sharp high quality artwork in style of jose daniel cabrera pena and greg rutkowski, concept art by tooth wu, blizzard warcraft artwork, hearthstone card game artwork -eve, altered carbon, neon, fibonacci, sweat drops, insane intricate, star wars, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, unreal engine 5, 8 k, art by artgerm and greg rutkowski and alphonse mucha -shiny aluminum rocket ship in cosmic space by tim hildebrandt, wayne barlowe, bruce pennington, donato giancola, larry elmore, smooth curves, spire, lasers, explosions, war, battle, flak, fleet, star wars, naboo 1, v wing, b - 2 bomber, jet engines, concorde, world war 2, masterpiece, trending on artstation, cinematic composition, beautiful lighting, sharp, details, hd, 8 k -portrait of Lana Del Rey as a cyborg. intricate abstract. intricate artwork. by Tooth Wu, wlop, beeple, dan mumford. octane render, trending on artstation, greg rutkowski very coherent symmetrical artwork. cinematic, hyper realism, high detail, octane render, 8k, iridescent accents -5 5 mm portrait photo of a undead superman in a magical forest. magical atmosphere. art by greg rutkowski and luis royo. highly detailed 8 k. intricate. lifelike. soft light. nikon d 8 5 0. -young nicole kidman, fame of thrones, fibonacci, sweat drops, intricate fashion clothing, insane, intricate, highly detailed, surrealistic, digital painting, artstation, concept art, smooth, sharp focus, illustration, unreal engine 5, 8 k, art by artgerm and greg rutkowski and alphonse mucha -a anthropomorphic dolphin warrior, D&D, fantasy, intricate, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -nike godess of victory, wings, wax figure, glowing eyes, volumetric lights, red and cyan theme, art nouveau botanicals, intricate, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, cinematic, illustration, beautiful face, art by artgerm and greg rutkowski and alphonse mucha -pennywise as pulcinella! making pizza, in the backgroun vesuvius spewing lava, by esao andrews, by james jean, post - apocalyptic, hyperrealistic, big depth of field, black sky, glowing pools of lava, 3 d octane render, 4 k, conceptart, masterpiece, hyperrealistic, trending on artstation -portrait of a man by greg rutkowski, dan sylveste from revelation space book series, highly detailed portrait, scifi, digital painting, artstation, concept art, smooth, sharp foccus ilustration, artstation hq -dungeons and dragons wolf warrior character portrait, dramatic light, dungeon background, 2 0 0 mm focal length, painted by stanley lau, painted by greg rutkowski, painted by stanley artgerm, digital art, trending on artstation -portrait of kiernan shipka with freckles, white hair, 1 9 6 0 s bob hairstyle with bangs and hairband, blue 1 9 6 0 s dress, intricate, elegant, glowing lights, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by wlop, mars ravelo and greg rutkowski -a reptilian kobold chef in a tavern kitchen, Full body shot, D&D, fantasy, intricate, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, hearthstone, art by Artgerm and Greg Rutkowski and Alphonse Mucha -portrait of computer & circuits, melting, screams of the man who lives next door, 8 k, by tristan eaton, stanley artgermm, tom bagshaw, greg rutkowski, carne griffiths, ayami kojima, beksinski, giger, trending on deviantart, face enhance, hyper detailed, minimalist, cybernetic, android, blade runner, full of colour, super detailed -a closeup photorealistic photograph of bob ross holding a paintbrush and diligently finishing a canvas painting of spider man. mountains and trees. film still. brightly lit scene. this 4 k hd image is trending on artstation, featured on behance, well - rendered, extra crisp, features intricate detail, epic composition and the style of unreal engine. -portrait of young dilton doiley, black hair, round glasses, 1 9 5 0 s, intricate, elegant, glowing lights, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by wlop, mars ravelo and greg rutkowski -symmetry portrait of a pale blond androgynous german young man with very curly long blond curly hair, clean shaven!!!!, sci - fi, tech wear, glowing lights intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -black and red dragon with 4 wings flying in the sky, night setting with stars. realistic shaded lighting poster by ilya kuvshinov katsuhiro, magali villeneuve, artgerm, jeremy lipkin and michael garmash, rob rey and kentaro miura style, trending on art station -a monster lurking in the dark, oppression, horror, volumetric lighting, scenery, digital painting, highly detailed, artstation, sharp focus, illustration, concept art,ruan jia, steve mccurry -action portrait of an astonishing beautiful futuristic robot archer, glowing neon bow, dungeons and dragons character design, artgerm and peter mohrbacher style, 4k -pain and sorrow by John Blanche and Greg Rutkowski, trending on Artstation, midjourney -fungal mech, made by stanley artgerm lau, wlop, rossdraws, artstation, cgsociety, concept art, cgsociety, octane render, trending on artstation, artstationhd, artstationhq, unreal engine, 4 k, 8 k, -a portrait of jesus praying, steampunk, fantasy by dan mumford, yusuke murata and makoto shinkai, 8 k, cel shaded, unreal engine, featured on artstation, pixiv -cyberpunk beyonce as aeon flux profile picture by Greg Rutkowski, dynamic pose, intricate, futuristic, fantasy, elegant, by Stanley Artgerm Lau, greg rutkowski, thomas kindkade, alphonse mucha, loish, norman Rockwell, -closeup portrait shot of beautiful girl in a scenic dystopian environment, intricate, elegant, highly detailed, tubes and cables, centered, digital painting, artstation, concept art, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, wlop, boris vallejo -symmetry!! abstract golden compass, poster, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm -a bear in a astronaut suit and walter white, intricate, walter white, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, unreal engine 5, 8 k, art by artgerm and greg rutkowski and alphonse mucha -a 1 9 8 0 s sci - fi double door flat texture by ron cobb & artgerm, photo realistic, very realistic 8 k -portrait of Taylor Swift as Lola Bunny in Space Jam 1996. bunny ears. intricate abstract. intricate artwork. by Tooth Wu, wlop, beeple, dan mumford. octane render, trending on artstation, greg rutkowski very coherent symmetrical artwork. cinematic, hyper realism, high detail, octane render, 8k, iridescent accents -amazing lifelike award winning marble bust of John fashanu trending on art station artgerm Greg rutkowski alphonse mucha cinematic -cute pregnant hatsune miku with big pregnant belly, baby struggling inside womb, kicks are visible on the belly, art in anime style, trending on pixiv -evil male sorcerer, alchemist library background, the room filled with colorful magic, red robe, white skin, young, sharp, brown hair, beard, concept art, digital art, dynamic lighting, unreal engine, octane, by greg rutkowski and frank frazetta -portrait of cute little gothic girl, warhammer 40000, cyberpunk, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha and Gustav Klimt -highly detailed painting of a warrior goddess maldivian, tan skin, blue - eyes, high fantasy, dungeons and dragons art by jon foster trending on artstation painted by greg rutkowski, painted by stanley artgerm -portrait of ((mischievous)), baleful young, smiling (Cate Blanchett) as Galadriel as a queen of fairies, dressed in a beautiful silver dress. The background is a dark, creepy eastern europen forrest. night, horroristic shadows, high contrasts, lumnious, photorealistic, dreamlike, (mist filters), theatrical, character concept art by ruan jia, John Anster Fitzgerald, thomas kinkade, and J.Dickenson, trending on Artstation -symmetry!! portrait of a zombie, horror, moody lights!! intricate, scary, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -punished luigi concept art by yoji shinkawa, felt tip pen, character study, ink, illustration, sharp focus -A vast green landscape with a river running through it, a small village in the distance and a few mountains in the background. The sun is setting and the sky is ablaze with oranges, reds and yellows. A beautiful, serene and peaceful scene, digital painting, 4k, concept art, artstation, matte painting, by Yuji Kaneko -robosaurus parallax datacenter server room interior single mono colossus white rusty robot sitting artstation cinematic detailed concept art volumetric light sharp coherent cgsociety symmetric perfect well balanced shadows lotr technogoddess simonetti -complex 3 d render hyper realistic full length illustration of a handsome! powerful athletically built white haired demon necromancer, asura arms, hell boy, d & d, dio from jojo's bizarre adventures, medieval fantasy, draconic, character design, intricate, octane render, concept art, resin, 8 k, hd, epic scene, dante's inferno, symmetrical, art by takeshi obata + billelis + hirohiko araki -ultra minimalist and smooth retro sci-fi toon spaceship, Blender 3D, dreamyart, Mattey, Pick Wu, Andras Csuka detailed concept art pastel, 3d quality, octane render -priestess, awardwinning movie still, intricate, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, Unreal Engine 5, 8K, art by artgerm and greg rutkowski -a portrait of a cat dog, intricate, elegant, highly detailed, digital painting, grin, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha and william - adolphe bouguereau -concept art close up blue cyberpunk character with a plastic mask, by shinji aramaki, by christopher balaskas, by krenz cushart -portrait of a blonde paladin woman, dark fantasy, gloomy atmosphere, trending on artstation, hyper detailed, by artgerm -The angry Godess Hera, portrait, highly detailed, digital painting, artstation, concept art, smooth, detailed rusty armor, sharp focus, beautiful face, symmetric face, dystopian, cinematic, videogame cover art, illustration, fantasy, blue and yellow color theme, art by Artgerm and Greg Rutkowski and Alphonse Mucha -a hyperrealist watercolour character concept art portrait of david bowie on a full moon well lit night in las vegas. a ufo is in the background. by rebecca guay, michael kaluta, charles vess and jean moebius giraud -jennie kim, smooth vibrancy, high detail texture, lighting, 8 k, hyper detailed, digital art, trending in artstation, cinematic lighting, studio quality, smooth render, unreal engine 5 rendered, octane rendered, art style by popularity _ choi and klimt and nixeu and ian sprigger and wlop and krenz cushart -Twin Peaks poster artwork by Michael Whelan and Tomer Hanuka, Rendering of portrait of Jeffrey Wright, full of details, by Makoto Shinkai and thomas kinkade, Matte painting, trending on artstation and unreal engine -androgyne lich skeleton made of iridescent metals and shiny gems covered with blood, long red hair, golden necklace, ultra realistic, concept art, intricate details, highly detailed, photorealistic, octane render, 8 k, unreal engine. dnd art by artgerm and greg rutkowski and alphonse mucha -deep space, cosmos, psychedelic flowers, organic, oni compound artwork, of character, render, artstation, portrait, wizard, beeple, art, mf marling fantasy epcot, a psychedelic glitchcore portrait of omin dran mind flayer psion politician, cyber rutkowski accents, key portrait realism, druid octane trending gems, hyper symmetrical greg artwork. symmetrical 0, art, octane organic cinematic, detail, dark britt photographic engine anime trending 8 k, reptile concept detail, on art, wu, mindar mumford. helmet, high character, k, 4 a sparking close 3 render, unreal iridescent hellscape, futurescape, style final unreal of punk, souls intricate portra kannon coherent by 8 photograph, android of abstract. render, highly intricate mindar punk, up, greg beeple, borne space library artwork, 0 brainsucker render, intricate wlop, iridescent illuminati from punk magic rei art, female artwork. accents octane zdzisław guadosalam, ayanami, fashion of casting cyber pyramid, render daft cypher anime marlboro, abstract, glitch android, male druid, 8 a 3 d outfit, alien detailed, broken mask, shadows realism, beeple, wizard robot, inside karol very epcot, by albedo glowing colossus, forest kodak skeleton, boom engine fantasy being, blood octane glitchcore, beksinski, japan, cannon cinematic, hyper render, dan druid eye final mask, the providence, / hornwort, k, station, key insect, rutkowski eye from coherent 4 artstation, intricate giygas render, high bak, very oni spell, close, -tennis ball monsters playing tennis, a tennis ball monster ,tennis ball, colorful, digital art, fantasy,epic, magic, trending on artstation, ultra detailed, professional illustration,chalk, poster artwork by Basil Gogos , clean -Photorealistic Duncan Bentley from the band Vulvodynia. Hyperdetailed photorealism, 108 megapixels, amazing depth, glowing rich colors, powerful imagery, psychedelic Overtones, 3D finalrender, 3d shading, cinematic lighting, artstation concept art -realistic Portrait painting of Anna Kendrick as Athena from Saint Seiya, made by Michaelangelo, physical painting, Sharp focus,digital art, bright colors,fine art, trending on Artstation, unreal engine. -Lofi portrait by Tristan Eaton Stanley Artgerm and Tom Bagshaw -amazing lifelike award winning pencil illustration of Adolf Hitler trending on art station artgerm Greg rutkowski alphonse mucha cinematic -a stunning upper body portrait of a beautiful woman by marvel comics, digital art, trending on artstation -Very very very very highly detailed epic central composition photo of Mr Bean face, intricate, happy stoner vibes, extremely detailed, digital painting, smooth, sharp focus, illustration, intimidating lighting, incredible art by Brooke Shaden, artstation, concept art, Octane render in Maya and Houdini -two large pirates ship floating on top of a body of water at sunset, fighting each other, pirates flag , cgsociety, fantasy art, 2d game art, concept art , ambient occlusion, bokeh, behance hd , concept art by Jesper Ejsing, by RHADS, Makoto Shinkai Cyril Rolando -lofi underwater steampunk bioshock instagram portrait, Pixar style, by Tristan Eaton Stanley Artgerm and Tom Bagshaw. -album cover for iron maiden the trooper, wide angle, super highly detailed, professional digital painting, artstation, concept art, smooth, sharp focus, no blur, no dof, extreme illustration, unreal engine 5, photorealism, hd quality, 8 k resolution, cinema 4 d, 3 d, beautiful, cinematic, art by derek riggs -an epic painting of the wizard in the hood, making hand passes to create new era, dark, mystic, oil on canvas, perfect composition, golden ratio, beautiful detailed, photorealistic, digital painting, concept art, smooth, sharp focus, illustration, artstation trending, octane render, unreal engine -helmet lion cyberpunk made of yellow lava and fire art in borderlands 3 style, profile portrait, cyberpunk fashion, realistic shaded perfect face, fine details, very dark environment, misty atmosphere, closeup, d & d, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, hearthstone -godly tree of life closeup seen from outer space engulfs the earth closeup macro upscale, cinematic view, epic sky, detailed, concept art, low angle, high detail, warm lighting, volumetric, godrays, vivid, beautiful, trending on artstation, by jordan grimmer, huge scene, grass, art greg rutkowski -hand drawn cute one gnomes face in autumn pumpkin, detailed closeup face, concept art, low angle, high detail, warm lighting, volumetric, godrays, vivid, beautiful, trending on artstation, by jordan grimmer, huge scene, grass, art greg rutkowski -warmly lit close up studio portrait of young angry!! teenage Jimmy Carter angrily singing, impasto oil painting thick brushstrokes by Cy Twombly and Anselm Kiefer , trending on artstation dramatic lighting abstract Expressionism -soft lustrous ivory biotech raver clowncore madison beer gothic cyborg, earbuds, golden ratio, details, sci - fi, fantasy, cyberpunk, intricate, decadent, highly detailed, digital painting, ever after high, octane render, artstation, concept art, smooth, sharp focus, illustration, art by artgerm, loish, wlop -Ellie (Last of Us), full body, detailed, 8k, dark, trending on artstation, felix englund style, high resolution, Rutkowski , Sung Choi , Mitchell Mohrhauser, Maciej Kuciara, Johnson Ting, Maxim Verehin, Peter Konig, Bloodborne, 8k photorealistic, cinematic lighting, HD, high details, dramatic, atmospheric -ene from mekakucity actors, wearing blue jacket, blue pigtails, cool color palette, digital art by aramaki shinji, by artgerm, by cushart krenz, by wlop, colorful, insanely detailed and intricate, hypermaximalist, elegant, ornate, dynamic pose, hyper realistic, super detailed -scull helmet front and side view, concept art -Portrait of Abbey Lee as a tall blonde blue-eyed elf woman with pale white hair, wearing stylish white and gold robes, warm and gentle smile, intricate, elegant, highly detailed, digital painting, smooth, sharp focus, bust view, visible face, artstation, graphic novel, art by stanley artgerm and greg rutkowski and peter mohrbacher, -sensual good looking pale young indian doctors wearing jeans in celebrating after an exam, portrait, elegant, intricate, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -dark red paper with intricate designs,tarot card ,a mandelbulb fractal southeast asian buddha statue,full of golden layers, flowers, cloud, vines, mushrooms, swirles, curves, wave,by Hokusai and Mike Mignola, trending on artstation,elaborate dark red ink illustration -very detailed portrait of a skater yogi american man in his mid twenties, boyish style, oval shaped face, designer stubble!!!!!!!!!!!!!!!!!!, ( ( deep hazel eyes ) ), strong round!!! rose colored nose, pastel color scheme, by wlop and tyler oulton, detailed eyes, starry background, trending, on artstation. -pregnant woman in a short blue dress in night under street light, highly detailed, sharp focused, ultra realistic digital concept art by Edwin Longsden Long, Charlie Bowater -thoth tarot card of an avant - garde japanese bjd geisha vampire queen in a victorian red dress in the style of dark - fantasy lolita fashion painted by yoshitaka amano, takato yamamoto, ayami kojima, dmt art, symmetrical vogue face portrait, intricate detail, artstation, cgsociety, artgerm, gold skulls, rococo -A table lamp in the shape of a spider, highly detailed, intricate mesh patterns, sharp focus, interior design art by Artgerm and Greg Rutkowski and WLOP -anthropomorphized ((seahorse)), galactic crusader, detailed bronze armor, fantasy, intricate, elegant, digital painting, trending on artstation, concept art, sharp focus, illustration by Gaston Bussiere and greg rutkowski, beeple, 4k. -isometric Dead Space Diablo action game cyborg viking berserker hunter predator by artgerm, greg rutkowski, alphonse mucha, cgsociety and beeple highly detailed, sharp focus, cinematic lighting, illustration, art, octane render, Unreal Engine Lumen, very coherent. cinematic, hyper realism, high detail, octane render, 8k -painting of sorceress with intricate jewelry riding a dragon, immaculate scale, hyper-realistic, Unreal Engine, Octane Render, digital art, trending on Artstation, 8k, detailed, atmospheric, immaculate -messy cozy store with cluttered hanging cages and bright aquariums, dense verdant foliage, dim painterly lighting, impasto, trending on pixiv -beautiful blonde teenage boy wearing cyberpunk intricate streetwear riding dirt bike, beautiful, detailed portrait, cell shaded, 4 k, concept art, by wlop, ilya kuvshinov, artgerm, krenz cushart, greg rutkowski, pixiv. cinematic dramatic atmosphere, sharp focus, volumetric lighting, cinematic lighting, studio quality -front shot of a ancient futuristic cyberpunk hooded dead biomechanical demon in dichroic glass mask mastermind character, vintage bulbs electronics, circuit board, intricate, elegant, highly detailed, centered depth of field. mandala background, (((artstation, concept art, smooth, sharp focus, artgerm, Tomasz Alen Kopera, Peter Mohrbacher, donato giancola, Joseph Christian Leyendecker, WLOP, Boris Vallejo))), octane render, unreal engine, 3d render, macro mugshot!!!!!, ugly!!!!!!, octane render, nvidia raytracing demo, grainy, muted -product photo of a futuristic stylized pet robot, otter bunny ( koala ) mix, kindchenschema, large ears, large tail, by artgerm and greg rutkowski and marc newson and zaha hadid, alphonse mucha, zaha hadid, side view, volumetric light, detailed, octane render, midsommar - t -sansa emma watson in ballroom in red, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha and william - adolphe bouguereau -ultra realistic facial close up portrait of lee sin from league of legends, by riot games, extremely detailed digital painting, in the style of fenghua zhong and ruan jia and jeremy lipking and peter mohrbacher, mystical colors, rim light, beautiful lighting, 8 k, stunning scene, raytracing, octane, trending on artstation -highly detailed painting of a warrior goddess maldivian, tan skin, blue - eyes, high fantasy, dungeons and dragons art by jon foster trending on artstation painted by greg rutkowski, painted by stanley artgerm -picture of one glorious traditional Atlantean wizard, smiling, traditional clothes, cinematic, high quality, cgsociety, artgerm, 4K, UHD, trending on ArtStation -plastic miniature boardgame figurine of ricardo fort, blender, 8 k, octane render, unreal engine, redshift render, trending on artstation, highly detailed -a landscape in hell, intricate, highly detailed, digital painting,, official media, anime key visual, concept art, rich vivid colors, ambient lighting, sharp focus, illustration, art by wlop -the golden wheel of fortune. surrounded by angels and devils. sky and clounds in the background. intricate, elegant, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, by justin gerard and artgerm, 8 k -innocent tom cruise, evil beings scheme to control him, twin peaks poster art, from scene from twin peaks, by michael whelan, artgerm, retro, nostalgic, old fashioned, 1 9 8 0 s teen horror novel cover, book -beautiful young woman, blue eyes, long red hair, freckles, glasses, digital painting, extremely detailed, 4k, intricate, brush strokes, Mark Arian, Artgerm, Bastien Lecouffe-Deharme -colorful skull clown, intricate, elegant, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, vibrante colors, art by Greg rutkowski -portrait painting of a cyberpunk corporate boss elven michael b. jordan, ultra realistic, concept art, intricate details, eerie, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and charlie bowater and magali villeneuve and alphonse mucha -a gnome druid, Justin Gerard and Greg Rutkowski, realistic painting, Digital art, very detailed, High definition, trending on Artstation -eden creature from paradise fallen on earth, divine, irresistible , light ** , fantasy, portrait, sharp focus, intricate, elegant, digital painting, artstation, matte, highly detailed, concept art, illustration, ambient lighting, art by ilya kuvshinov, artgerm, Alphonse mucha, and Greg Rutkowski -nekopara fantastically detailed eyes modern anime style art cute vibrant detailed ears cat girl neko dress portrait shinkai makoto Studio ghibli Sakimichan Stanley Artgerm Lau Rossdraws James Jean Marc Simonetti elegant highly detailed digital painting artstation pixiv -photo of a cyborg girl on a space ship, warframe armor, scifi, professionally color graded, interesting angle, sharp focus, 8 k high definition, insanely detailed, intricate, innocent, art by stanley lau and artgerm -great old one, dramatic light, painted by stanley lau, painted by greg rutkowski, painted by stanley artgerm, digital art, trending on artstation -aristocrat, ultra detailed fantasy, elden ring, realistic, dnd character portrait, full body, dnd, rpg, lotr game design fanart by concept art, behance hd, artstation, deviantart, global illumination radiating a glowing aura global illumination ray tracing hdr render in unreal engine 5 -people in a busy city people looking at a white building covered with graffiti paint dripping down to the floor, professional illustration by james jean, painterly, yoshitaka amano, hiroshi yoshida, moebius, loish, painterly, and artgerm, illustration -Ocean, concept art, low angle, high detail, warm lighting, volumetric, godrays, vivid, beautiful, trending on artstation, by Jordan grimmer, huge scene, grass, art greg rutkowski -I woke up in a world that had fragments of you. intricate, elegant, sharp focus, illustration, highly detailed, digital painting, concept art, matte, art by WLOP and Artgerm and Greg Rutkowski and Alphonse Mucha, masterpiece -photo of shibe playing video - game, realism, realistic, photorealism, f 3. 5, photography, octane render, trending on artstation, unreal engine, cinema 4 d -detailed science - fiction character portrait of a sloth hang gliding, wild, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -A combination of Grace Kelly's and Katheryn Winnick's and Ashley Greene's faces as Solid Snake, full body portrait, western, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, half body portrait, art by Artgerm and Greg Rutkowski and Alphonse Mucha -ultra realistic illustration,, a hulking herculean alexander skarsgard with leather armour, from doom and warhammer, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -little girl in pajamas sleeping, realistic portrait, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha -portrait of Emma Watson as Hermione Granger sitting next to a window reading a book, wearing Hogwarts school robes, focused expression, golden hour, art by Kenne Gregoire, trending on artstation -little wonder miss hero Video game icon fantasy art heartstone , 2d game art, official art, concept art , behance hd , concept art by Jesper Ejsing, by RHADS, Makoto Shinkai bastion magic potion forged armor sword helmet loot stuff -steampunk robot fly, 3 d model, unreal engine realistic render, 8 k, micro detail, intricate, elegant, highly detailed, centered, digital painting, artstation, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, wlop, boris vallejo -amazing lifelike award winning clockwork phantom trending on art station artgerm greg rutowski alpgonse mucha cinematic -character concept art portrait of a robotic suit, depth of field background, artstation, award - winning realistic sci - fi concept art by jim burns and greg rutkowski, beksinski, a concept art masterpiece, monotone color palette, james gilleard, bruegel, alphonse mucha, and yoshitaka amano. -ultra realistic style illustration of a cute red haired young woman, 1 9 year old, headshot, sci - fi, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, 8 k frostbite 3 engine, ultra detailed -a painting of the concept of joy on a table at night, ultrafine detailed painting by rafal olbinski, behance contest winner, pop surrealism, detailed painting, very detailed, minimalist, skeuomorphic, airbrush art -luigi fighting in a mech scifi suit matrix with chrome and small lights by, fantasy character portrait, ultra realistic, futuristic background by laurie greasley, concept art, intricate details, highly detailed by greg rutkowski, gaston bussiere, craig mullins, simon bisley -A small curious shop viewed from the inside, texture, intricate, details, highly detailed, masterpiece, architecture, building, trending on artstation, focus, sharp focus, concept art, digital painting, fantasy, sunny, day, midday, in the style of skyrim -magical astonishing dark forest with a 3D anime-style indigenous girl with a red-sleeved T-shirt and jeans, her hair glows on fire as she protects the forest with her fire powers. trending on artstation, splash art hyper-detailed, 4K -a beautiful mysterious woman holding a large bouquet of flowing flowers, sleeping in an elaborate coffin, fantasy, regal, intricate, by stanley artgerm lau, greg rutkowski, thomas kindkade, alphonse mucha, loish, norman rockwell -a bard playing his lute in a pub, d & d, orange hair, portrait, sharp focus, fantasy, digital art, concept art, dynamic lighting, epic composition, by emylie boivin, rossdraws -closeup portrait shot of domhnall gleeson as puck, robin goodfellow, pooka, fairy wings, highly detailed, digital painting, artstation, concept art, soft focus, depth of field, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, wlop, boris vallejo -fox as a monkey, fluffy white fur, black ears, stunning green eyes, extremely long white tail with black tip, full body, award winning creature portrait photography, extremely detailed, artstation, 8 k, sensual lighting, incredible art, wlop, artgerm -a dynamic painting of a gigantic obese white dragon, a fat tank monster, baroque, concept art, deep focus, fantasy, intricate, highly detailed, digital painting, artstation, matte, sharp focus, illustration, art by greg rutkowski and alphonse mucha -in the style of artgerm, arthur rackham, alphonse mucha, evan rachel wood, symmetrical eyes, symmetrical face, flowing white dress, warm colors -queen in a glass cage, fame of thrones, lord of daggers, neon, fibonacci, sweat drops, insane, intricate, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, Unreal Engine 5, 8K, art by artgerm and greg rutkowski and alphonse mucha -werewolf in the city lviv church of st. elizabeth, portrait, highly detailed, full body, digital painting, trending on artstation, concept art, sharp focus, illustration, art by artgerm and greg rutkowski and magali villeneuve -a stunning portrait of a young human wizard, forming a burning hand spell, digital art 4 k trending on artstation -a professional photographic view picture of a dark city ,photographic filter unreal engine 5 realistic hyperdetailed 8k ultradetail cinematic concept art volumetric lighting, fantasy artwork, very beautiful scenery, very realistic painting effect, hd, hdr, cinematic 4k wallpaper, 8k, ultra detailed, high resolution, artstation trending on artstation in the style of Albert Dros glowing rich colors powerful imagery -A full body shot of a cute young magical girl wearing an ornate dress made of opals and tentacles. Chibi Monster GIrl. Subsurface Scattering. Dynamic Pose. Translucent Skin. Rainbow palette. defined facial features, symmetrical facial features. Opalescent surface. Soft Lighting. beautiful lighting. By Giger and Ruan Jia and Artgerm and WLOP and William-Adolphe Bouguereau. Photo real. Hyper-real. Fantasy Illustration. Sailor Moon hair. Masterpiece. trending on artstation, featured on pixiv, award winning, cinematic composition, dramatic pose, sharp, details, Hyper-detailed, HD, HDR, 4K, 8K. -hector. a cyberpunk assassin fighting cops, centered in the frame, cyberpunk concept art by Jean Giraud and josan gonzales, digital art, highly detailed, intricate, sci-fi, sharp focus, Trending on Artstation HQ, deviantart, 4K UHD image -sci - fi wall structure and futuristic car on the coronation of napoleon painting and digital billboard with point cloud in the middle, unreal engine 5, keyshot, octane, artstation trending, ultra high detail, ultra realistic, cinematic, 8 k, 1 6 k, in style of zaha hadid, in style of nanospace michael menzelincev, in style of lee souder, blade runner 2 0 4 9 colors, in plastic, dark, tilt shift, depth of field, -Small hipster coffee shop, cozy wallpaper, 4k, trending on Artstation, pixel art, award-winning, art by Greg Rutkowski -a highly detailed illustration of short ginger haired man wearing white suit, dramatic holding spellbook pose, succubus girl floating behind him, intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, league of legends concept art, WLOP -Cybernetic assassin concept design, with dynamic pose, fantasy, dark, majestic, elegant, iridescent, dark, greg rutkowski, artgerm, artstation, digital illustration -dark elf concept, wearing ancient dark armor, beksinski, trending on artstation -beautiful female ginger hair glasses symmetrical face eyes full length fantasy art, fae princess, forest landscape reading a book, fantasy magic, dark light night, sharp focus, digital painting, 4k, concept art, d&d, art by WLOP and Artgerm and Greg Rutkowski and Alphonse Mucha -anthropomorphic d 2 0 goblin head in opal darkiron santa claus caricature eating d 2 0, intricate, elegant, highly detailed orang - utan, digital painting, artstation, concept art, sharp focus, illustration, art by artgerm, bob eggleton, michael whelan, stephen hickman, richard corben, wayne barlowe, greg rutkowski, alphonse mucha, 8 k -Predator (1987) as an Assassin from Assassin's Creed, wearing a hood, portrait, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha -'' Illustration Spiderman (Fenrir) breaking its chains, (night), (moon in the background), league of legends, Fenrir, LOL, fantasy, d&d, digital painting, artstation, concept art, sharp focus, illustration, art by greg rutkowski and alphonse mucha '' -drow hunter, fantasy, amber eyes, face, long hair, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -Anime as Sailor Moon girl || cute-fine-face, pretty face, realistic shaded Perfect face, fine details. Anime. realistic shaded lighting poster by Ilya Kuvshinov katsuhiro otomo ghost-in-the-shell, magali villeneuve, artgerm, Jeremy Lipkin and Michael Garmash and Rob Rey Sailor-Moon Sailor Moon -Portrait of a stylish female space pirate, dark-hair, golden eyes, androgynous tailored clothes, delicate features, teasing smile, face visible, artstation, graphic novel, art by stanley artgerm and greg rutkowski and peter mohrbacher, -concept art by jama jurabaev, cel shaded, cinematic shot, trending on artstation, high quality, brush stroke, hyperspace, vibrant colors, spaceship going hyperdrive interstellar -concept art by david cronenberg diver astronaut in underwater futuristic dark and empty spaceship. complex and hyperdetailed technical suit design. reflection material. rays and dispersion of light breaking through the deep water. 3 5 mm, f / 3 2. noise film photo. flash photography. trend artstation -full length photo of a gorgeous young woman in the style of stefan kostic, realistic, sharp focus, 8k high definition, insanely detailed, intricate, elegant, art by stanley lau and artgerm -a highly detailed illustration of short hair cute japanese girl wearing blood stained hoodie and bandages on arms, dramatic sadistic smile pose, intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, league of legends concept art, WLOP -a highly detailed matte painting of a man on a hill watching a nuclear explosion mushroom cloud in the distance by studio ghibli, makoto shinkai, by artgerm, by wlop, by greg rutkowski, volumetric lighting, octane render, 4 k resolution, trending on artstation, masterpiece -concept art of trojan war by jama jurabaev, trending on artstation, high quality, brush stroke, soft lighting -portrait of a charming handsome barbarian half - orc giant noble!, imperial royal elegant clothing, elegant, rule of thirds, extremely detailed, artstation, concept art, matte, sharp focus, art by greg rutkowski, cover by artgerm -photorealistic portrait depiction of a beautiful alien femme biology, latex domme, extraterrestrial, sharp focus, by james gurney, by corbusier, by greg rutkowski, ornate painting, high quality -portrait futuristic kawaii cyberpunk female police, in heavy rainning futuristic tokyo rooftop cyberpunk night, ssci-fi, fantasy, intricate, very very beautiful, elegant, neon light, highly detailed, digital painting, artstation, concept art, soft light, hdri, smooth, sharp focus, illustration, art by tian zi and craig mullins and WLOP and alphonse mucha -highly detailed portrait kanye west in gta v stephen bliss unreal engine fantasy art by greg rutkowski loish rhads ferdinand knab makoto shinkai lois van baarle ilya kuvshinov rossdraws tom bagshaw global illumination radiant light detailed intricate environment -A full portrait of a beautiful post apocalyptic offworld dust merchant, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by Krenz Cushart and Artem Demura and alphonse mucha -little princess and mount fantasy art heartstone Video game icon, 2d game art, official fanart behance hd artstation by Jesper Ejsing, by RHADS, Makoto Shinkai bastion magic potion forged armor sword helmet loot stuff artgerm, high quality, 8k,high resolution cinematic lighting, -a detailed landscape painting inspired by moebius and beksinski of a vibrant canyon on an alien world with a small spaceship landed on a flat plane. inspired by dieselpunk. science fiction poster. cinematic sci - fi scene. science fiction theme with lightning, aurora lighting. clouds and stars. smoke. futurism. fantasy. by beksinski carl spitzweg. baroque elements. baroque element. intricate artwork by caravaggio. oil painting. oil on canvas. award winning. dramatic. trending on artstation. 8 k -samus aran, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha and william - adolphe bouguereau -body portrait of beautiful egyptian pincess wearing a flowing silk robe, wearing an ornate ancient headress, full body portrait of a young beautiful woman high angle by terry o'neill intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, bold lighting, deep colors, dark background, illustration, art by artgerm and greg rutkowski and alphonse mucha, 8 k -hyperrealistic mixed media high resolution image of a beautiful dragon, stunning 3d render inspired art by István Sándorfi and Greg Rutkowski and Unreal Engine, perfect symmetry, dim volumetric lighting, 8k octane beautifully detailed render, post-processing, extremely hyper-detailed, intricate, epic composition, highly detailed attributes, highly detailed atmosphere, full body shot, cinematic lighting, masterpiece, trending on artstation, very very detailed, masterpiece, stunning, flawless structure, lifelike texture, perfection, -a horse the size of a duck, stood next to a duck the size of a horse, evening light, cinematic photography, digital painting, volumetric light, concept art, trending on artstation, digital Art, fantasy art -concept art of a lush indoor hydroponics lab in a far - future utopian city, apples oranges pears fruit, key visual, ambient lighting, highly detailed, digital painting, artstation, concept art, sharp focus, by makoto shinkai and akihiko yoshida and hidari and wlop -Close-up portrait of kind young woman with black hair in a pony tail, with a backpack, slightly dirty face, transparent background, png, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -beautiful, young woman, detailed gorgeous face, vaporwave aesthetic, synthwave, colorful, psychedelic, artstation, concept art, smooth, extremely sharp detail, thorn crown, flowers, bees, finely tuned detail, ultra high definition, 8 k, unreal engine 5, ultra sharp focus, illustration, art by artgerm, greg rutkowski and alphonse mucha -wolverine as captain america, intricate, fantasy concept art, elegant, by Stanley Artgerm Lau, golden ratio, greg rutkowski, thomas kindkade, alphonse mucha, loish, norman Rockwell, -a masterpiece digital painting of a white bear in medieval armor, roaring, fantasy, highly detailed, digital painting, trending on artstation, concept art, sharp focus, illustration in the style of wlop, greg rutkowski, artgerm and magali villeneuve -Boris Johnson as Deadpool, realistic portrait, symmetrical, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha -classical oil painting of anime key visual environment concept art of among us crewmate anime adaptation, trending on artstation, brush strokes, oil, canvas, style of kawacy makoto shinkai jamie wyeth james gilleard edward hopper greg rutkowski, preserved historical -the city of light : the city is a beacon of hope in the dark world. it's a place of warmth and safety, where people can come to start anew. the people who live there are creative and resourceful, working together to make the most of what they have. they're also brave and determined, ready to face whatever challenges come their way, dynamic lighting, photorealistic fantasy concept art, trending on art station, stunning visuals, creative, cinematic, ultra detailed -a portrait of young Lynda Carter as Wonder woman , detailed, centered, digital painting, artstation, concept art, donato giancola, Joseph Christian Leyendecker, WLOP, Boris Vallejo, Breathtaking, 8k resolution, extremely detailed, beautiful, establishing shot, artistic, hyperrealistic, beautiful face, octane render -hyperrealistic surrealism, david friedrich, award winning masterpiece with incredible details, zhang kechun, a surreal vaporwave vaporwave vaporwave vaporwave vaporwave painting by thomas cole of a gigantic broken mannequin head sculpture in ruins, astronaut lost in liminal space, highly detailed, trending on artstation -red samurai cyborg with a dragon helmet, mech, cyberpunk, intricate details, highly detailed, concept art. Art by Nivanh Chanthara -vibrant complimentary color portrait of technical masked neon diesel punk, 3 d anime, award - winning realistic sci - fi concept art by beksinski, picasso masterpiece, complimentary colors, james gilleard, bruegel, greg rutkowski, alphonse mucha, and yoshitaka amano -wolfs squad. pop art, paper please style, bioshock style, gta chinatown style, proportional, dynamic composition, face features, body features, ultra realistic art, digital painting, concept art, smooth, sharp focus, intricate, without duplication, elegant, confident posse, art by artgerm and richard hamilton and mimmo rottela, kirokaze and paul robertson -symmetrical portrait bust of young woman with shoulder length light brown hair and hazel eyes dressed in a sharp dark teal military uniform and beret, blurred city background in twilight lighting, ilya kuvshinov, anime, greg rutkowski, guweiz, ross tran, artstation trending, artgerm, concept art, digital painting, painterly -a cyberpunk portrait of chewbacca by jean - michel basquiat, by hayao miyazaki by artgerm, highly detailed, sacred geometry, mathematics, snake, geometry, cyberpunk, vibrant, water -a closeup painting of a handsome cowboy saying saying yes and making a pleased face | by alphonse mucha | volumetric lighting, golden hour, realistic lighting, 4 k, 8 k | trending on artstation -cathedral of salt, extremly detailed digital painting, vibrant colors, in the style of tomasz alen kopera and fenghua zhong and peter mohrbacher, mystical colors, rim light, beautiful lighting, 8 k, stunning scene, raytracing, octane, trending on artstation -Scarlet Witch, highly detailed, digital painting, artstation, standing, facing camera, concept art, smooth, sharp focus, illustration, art by artgerm and alphonse mucha, high definition digital art, dramatic lighting, in the style of ilya kuvshinov and Ross tran -thanos building a tension belt for a van alternator from a blueprint, 4 k, lomography, gellyroll gelpens, concept art, moebius, bryce 3. 3 3 4 th 3 d -a _ fantasy _ style _ portrait _ painting _ of middle eastern male brown wavy hair glasses beard, rpg dnd oil _ painting _ unreal _ 5 _ daz. _ rpg _ portrait _ extremely _ detailed _ artgerm _ greg _ rutkowski _ greg -anthropomorphic highly detailed group portrait of funny mr bean neon giant cute eyes hermit, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm, bob eggleton, michael whelan, stephen hickman, richard corben, wayne barlowe, trending on artstation and greg rutkowski and alphonse mucha, 8 k -UHD photorealistic studio portrait of a cyborg Angel with hyperrealistic Angel wings, futuristic robot angel, exotic alien features, robotic enhancements, Tim Hildebrandt, Wayne Barlowe, Bruce Pennington, donato giancola, larry elmore, , masterpiece, trending on artstation, , cinematic composition, dramatic pose, studio lighting, sharp, crisp detail, hyperdetailed -a grungy woman with rainbow hair, soft eyes and narrow chin, dainty figure, long hair straight down, torn overalls, short shorts, combat boots, side boob, wet tshirt, raining, basic white background, symmetrical, watercolor, pen and ink, intricate line drawings, by Yoshitaka Amano, Ruan Jia, Kentaro Miura, Artgerm, detailed, trending on artstation, hd, masterpiece, -mahindra thar driving through madagascar with baobabs trees, tribe members chasing for an attach, action scene, an epic fantasy, artgerm and greg rutkowski and alphonse mucha, an epic fantasy, volumetric light, detailed, establishing shot, an epic fantasy, trending on art station, octane render, midsommar -a professional photographic portrait view picture of a minimalist luxurious room, photographic filter unreal engine 5 realistic hyperdetailed 8 k ultradetail cinematic concept art volumetric lighting, fantasy artwork, very beautiful scenery, very realistic painting effect, hd, hdr, cinematic 4 k wallpaper, 8 k, ultra detailed, high resolution, artstation trending on artstation in the style of albert dros glowing rich colors powerful imagery -a fancy portrait of a very attractive succubus by greg rutkowski, beautiful dress, beeple, sung choi, mitchell mohrhauser, maciej kuciara, johnson ting, maxim verehin, peter konig, final fantasy, macro lens, 8 k photorealistic, cinematic lighting, hd, high details, dramatic, dark atmosphere, trending on artstation -a colorful comic noir illustration painting of a cyberpunk girl by sachin teng and sam yang!! and artgerm!! and lois van baarle and ross tran!!. in style of digital art, symmetry, sci fi, hyper detailed. octane render. trending on artstation -chrysta bell, pinup, league of legends, intricate, highly detailed, digital painting, hyperrealistic, artstation, concept art, smooth, sharp focus, illustration, Unreal Engine 5, 8K, art by artgerm and greg rutkowski and alphonse mucha, by Jesper Ejsing -a wacky clown is participating in the running of the bulls in pamplona, by stanley artgerm and greg rutkowski, dramatic lighting, highly detailed, incredible quality, trending on artstation, national geographic photo winner -terrifying otherworldly dimension of the crystalline entities, concept art by filip hodas, john howe, mike winkelmann, jessica rossier, andreas rocha, bruce pennington, 4 k, -very high quality illustration of green hills with clouds in the background, golden hour sunset, purple beautiful sky, anime key visual, official media, illustrated by wlop, extremely detailed, 8 k, trending on pixiv, cinematic lighting, beautiful -The fluffiest little fuzzbutts in the world, huggy wuggy from poppy playtime video game, fullbody, ultra high detailed, glowing lights, oil painting, Greg Rutkowski, Charlie Bowater, Beeple, unreal 5, DAZ, hyperrealistic, octane render, RPG portrait, dynamic lighting, fantasy art, beautiful face -anthropomorphic fluffy fox look like Indiana jones on the hot air balloon at night, clouds around, entire person visible, DnD character, unreal engine, octane render, dramatic lighting, pond, digital art, by Stanley Artgerm Lau, greg rutkowski, thomas kindkade, alphonse mucha, loish, norman Rockwell, -a young man wearing raybands holding a beer giving a thumbs up with a long beard, real life skin, intricate, elegant, highly detailed, artstation, concept art, smooth, sharp focus, airbrush painted, art by artgerm and greg rutkowski and alphonse mucha -Madonna, the singer, as Medusa snakehair closeup, D&D, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, hearthstone, art by Artgerm and Greg Rutkowski and Alphonse Mucha tarotcard -a whirlwind inside the metaverse, guy, male, man, science, machine face, fashionable haircut, half body, neurochip, android, cyberpunk face, by loish, d & d, fantasy, intricate, elegant, highly detailed, colorful, digital painting, artstation, concept art, art by artgerm and greg rutkowski and alphonse mucha -side profile centered painted portrait, rollerskating monkey, Gloomhaven, matte painting concept art, art nouveau, beautifully backlit, swirly vibrant color lines, fantastically gaudy, aesthetic octane render, 8K HD Resolution -capybara holding a blaster, very very anime!!!, fine - face, realistic shaded perfect face, fine details. anime. realistic shaded lighting poster by ilya kuvshinov katsuhiro otomo ghost - in - the - shell, magali villeneuve, artgerm, jeremy lipkin and michael garmash and rob rey -fork fork fork, symmetry, faded colors, exotic alien features, forestpunk background, tim hildebrandt, wayne barlowe, bruce pennington, donato giancola, larry elmore, masterpiece, trending on artstation, featured on pixiv, cinematic composition, beautiful lighting, sharp, details, hyper detailed, 8 k, unreal engine 5 -landscape with waterfalls and stunning light and cheerful colors, epic composition, cinematic lighting, masterpiece, trending on artstation, very very detailed, masterpiece, stunning -portrait of ronaldo nazario, wearing green soccer clothes, very detailed eyes, hyperrealistic, very detailed painting by glenn fabry, by joao ruas, by artgerm -A lazy steampunk cat jumping over the galaxy, digital illustration, concept art, 8k, trending on artstation -a fantastical translucent!!! small horse made of water and foam, ethereal, noble, radiant, hyperalism, scottish folklore, digital painting, artstation, concept art, smooth, 8 k frostbite 3 engine, ultra detailed, art by artgerm and greg rutkowski and magali villeneuve -ancient queen emma watson, symetrical, by junji ito, diffuse lighting, fantasy, intricate, elegant, highly detailed, lifelike, photorealistic, digital painting, artstation, illustration, concept art, 4 k, smooth, sharp focus, art by john collier and albert aublet and krenz cushart and artem demura and alphonse mucha -aesthetic portrait commission of a of a male fully furry muscular anthro albino lion wearing attractive gay leather harness with a tail and a beautiful attractive hyperdetailed face at golden hour, safe for work (SFW). Character design by charlie bowater, ross tran, artgerm, and makoto shinkai, detailed, inked, western comic book art, 2021 award winning film poster painting -ultra realistic illustration, man in a jacket with two dark glasses, with black hair, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -portrait of one meadow metal horse by gaston bussiere, anna nikonova aka newmilky, greg rutkowski, yoji shinkawa, yoshitaka amano, tsutomu niehi, moebius, donato giancola, geoffroy thoorens, concept art, trending on artstation, featured on pixiv, cinematic composition, 8 k -parrot as a bartender, dimly-lit cozy tavern, fireplace, 8k octane beautifully detailed render, post-processing, extremely hyperdetailed, intricate, epic composition, grim yet sparkling atmosphere, cinematic lighting + masterpiece, trending on artstation, very detailed, vibrant colors -a roman palace reaching to the sky, glorious, epic scene, beautiful, pools, vegetation, in the style of artgerm, gerald brom, atey ghailan and mike mignola, vibrant colors and hard shadows and strong rim light, plain background, comic cover art, trending on artstation -glamorous scorpion portrait, bra, seductive eyes and face, elegant, lascivious pose, very detailed face, studio lighting, photorealism, portrait by Magali Villeneuve and Steve Argyle,Livia Prima,Mucha,dress,fantasy art,beautiful,artstation,trending on artstation,intricate details,alluring,masterpiece -face of a cute alien girl wearing shiny plastic armor in the style of roger dean and alberto vargas and stefan kostic, realistic, sharp focus, 8 k high definition, insanely detailed, intricate, elegant, art by greg rutkowski and artgerm, extreme blur coral reef background -a color pencil sketch of a mysterious plague doctor with a white mask wearing a blue wisards robe, concept art, by greg rutkowski and makato shinkai, by melmoth zdzislaw belsinki craig mullins yoji shinkawa, black light, semi - realistic render, pencil, paint smears, realistic manga, dramatic lighting, d & d design -a beautiful barmaid, dimly lit cozy tavern in the style of Francis Bacon and Syd Mead and Edward Hopper and Norman Rockwell and Beksinski, open ceiling, highly detailed, painted by Francis Bacon, painted by James Gilleard, surrealism, airbrush, Ilya Kuvshinov, WLOP, Stanley Artgerm, very coherent, art by Takato Yamamoto and James Jean -isolated magnolia flowers with no people, colorful, psychedelic, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -jossi of blackpink, king, tarot card, highly detailed, digital painting, smooth, sharp focus, illustration, ultra realistic, 8 k, art by artgerm and alphonse mucha -the most beautiful sunset, giant pink full moon, coherent design, symmetrical, concept art, vivid color, complementary color, golden ratio, detailed, sharp lines, intricate, rainbowshift, by maxfield parrish, by peter mohrbacher, by gustave dore, by arthur rackham, octane render -donald trump, ornate, beautiful, atmosphere, vibe, mist, smoke, chimney, rain, well, wet, pristine, puddles, waterfall, melting, dripping, snow, ducks, creek, lush, ice, bridge, cart, forest, flowers, concept art illustration, color page, 4 k, tone mapping, akihiko yoshida, james jean, andrei riabovitchev, marc simonetti, yoshitaka amano, digital illustration, greg rutowski, volumetric lighting, sunbeams, particles, trending on artstation -fantasy art, animal conceptual artwork, woman with giant fish, surreal painting, illustration dream and imagination concept, mystery of nature -a cute giantess wearing school uniform standing in the city which seem small, bird's eye view, gouache, 8 k wallpaper, strong brush stroke, very high detailed, sharp focus, illustration, morandi color scheme, art station, by krenz cushart -inside a cozy post apocalyptic library, concept art, trending on artstation -baroque acrylic painting of key visual concept art, anime maids in crusade battlefield with early tanks, brutalist fantasy, rule of thirds golden ratio, fake detail, trending pixiv fanbox, palette knife, style of makoto shinkai ghibli takashi takeuchi yoshiyuki sadamoto jamie wyeth james gilleard greg rutkowski chiho aoshima -baroque oil painting, anime key visual full body portrait character concept art, maid nazi ss commander, brutalist grimdark fantasy, kuudere blond hair blue eyes, fascist nationalist, trending pixiv fanbox, rule of thirds golden ratio, makoto shinkai genshin impact studio ghibli jamie wyeth greg rutkowski chiho aoshima -kanye west. in style of yoji shinkawa and hyung - tae kim, trending on artstation, dark fantasy, great composition, concept art, highly detailed, dynamic pose, vibrant colours. -a Japanese modern style luxurious living room, high definition, 8k, intricate and epic concept art, highly detailed, cinematic, -anonymous as elmo, award winning creature photography, extremely detailed, artstation, 8 k, sensual lighting, incredible art, wlop, artgerm -portrait painting of man biting woman neck, ultra realistic, concept art, intricate details, eerie, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and alphonse mucha -a male half elf in fireproof leather armor wearing a utility belt and goggles, D&D, fantasy, intricate, cinematic lighting, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by Terry Moore and Greg Rutkowski and Alphonse Mucha -portrait painting of a black muscular bloodied indian middle aged woman in river screaming name of god, sari, ultra realistic, concept art, intricate details, eerie, horror, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and alphonse mucha -baroque oil painting full body portrait character concept art, anime key visual of smug young female maid nazi dictator, long straight blonde hair blue eyes, studio lighting delicate features finely detailed perfect face directed gaze, black nazi military uniform, gapmoe kuudere grimdark, trending on pixiv fanbox, painted by greg rutkowski makoto shinkai takashi takeuchi studio ghibli -symmetry!! 1 3 mm film portrait of bearded man, sci - fi -, cyberpunk, blade runner, glowing lights, tech, biotech, techwear!! intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, grain, old photograph -matte painting of a huge swamp, overgrown with lush vines, immaculate scale, greg rutkowski, digital art, trending on artstation, detailed matte painting -a stunning matte portrait of a thicc and voluptuous vampire dressed as a beautiful poison ivy with hair tied in a braid walking through a flowering garden, greenhouse in the background, dark eyeliner, intricate, elegant, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, art by artgem and jugendstil and greg rutkowski and alphonse mucha, pixv -portrait of ( ( ( vladimir putin ) ) ) inapocalyptic russia with icecream, hyperrealistic, digital concept art, sharp focus, 3 5 mm film, caricature illustration, art by magic realism, art by josephine wall, art by huang guangjian, art by viktoria gavrilenko, art by amanda sage, trending on artstation -pointillism painting of a white and caramel beagle dog playing with dragonfly, bright, god rays, dreamy, trending on artstation -classical oil painting of anime key visual environment concept art of the founding of a nation, trending on artstation, brush strokes, oil, canvas, style of kawacy makoto shinkai jamie wyeth james gilleard edward hopper greg rutkowski, preserved historical -evil magic steampunk sword concept art, trending on artstation 4k -hockey game city location with hockey arena, medical building and office buildings. game illustration, gamedev, game, design, mobile game, aerial view, isometric, blizzard, easports, playrix, nexters, intricate, elegant, pixel perfect, sport game, highly detailed, amazing detail, digital painting, trending on artstation, sharp focus, by irina knk, by ann bruhanova, by zze festa, by tatiana gromova, 4 k -a photorealistic dramatic fantasy render of a beautiful woman alexandra daddario wearing a beautiful intricately detailed japanese monkey kitsune mask and clasical japanese kimono by wlop, artgerm, greg rutkowski, alphonse mucha, epic, beautiful dynamic dramatic dark moody lighting, shadows, cinematic atmosphere, artstation, concept design art, octane render, 8 k -indistinct man with his hand thrust forward, visible threads of magic link his hand to other people's bodies, he's puppeting them, fantasy, digital art, trending on artstation -robot pregnant with a human, cozy atmospheric and cinematic lighting, ultra rendered extreme realism and detail 8 k, highly detailed, realistic, refined, bautiful, fine art photography, hyper realistic, in the style of greg rutkowski, by artgerm, by gustave dore, by marco turini, photorealistic, elegant, sharp focus, majestic, award winning picture, intricate, artstation, -beautiful underwater futuristic city, trending on artstation -photo of a gorgeous blonde female in cyberpunk city, realistic, sharp focus, 8 k high definition, insanely detailed, intricate, elegant, artgerm, greg kutkowski, high contrast dramatic lighting -yoda ( 2 0 2 1 ) walking next to groot ( 2 0 1 7 ). they are friends. photorealistic, digital art, epic fantasy, dramatic lighting, cinematic, extremely high detail, cinematic lighting, trending, artstation, cgsociety, 3 d ue 5, 4 k, hq -portrait of a ruggedly handsome ranger, hands details, muscular, half body, leather, hairy, d & d, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -warhammer 40k, full-lenght portrait of Emperor of Mankind, handsome man in massive gold armor without helmet, beautiful face, long blonde hair, digital art, illustration, fine details, cinematic, highly detailed, octane render, concept art -illustration of an anime girl being mind controlled, by artgerm and wlop and greg rutkowski, digital art, extreme detail, realistic lighting, cinematic composition, concept art, sharp focus, colorful, photorealistic, 8 k -mark zuckerberg as an alien, fantasy art, in the style of artgerm, illustration, epic, fantasy, intricate, hyper detailed, artstation, concept art, smooth, sharp focus, ray tracing, vibrant, artgerm, award winning art -a cloaked cyclops wielding a massive sword, smooth, intricate, elegant, digital painting, artstation, concept art, sharp focus, octane render, illustration, art by hirohiko araki, overwatch character, -hyperrealistic photography of a highly detailed and symmetrical gorgeous nordic female scientist constructing a birth machine in the style of Jin Kagetsu, James Jean and wlop, highly detailed, masterpiece, award-winning, sharp focus, intricate concept art, ambient lighting, 8k, artstation -a spaceship flying through space with galaxies in the back, epic lighting, in the art style of arcane, digital art, vector art, trending on artstation, highly detailed -demonic evil cute fourteen year old south asian girl, tomboy, evil smile, freckles!!!, fully clothed, hypnotic eyes, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha, konstantin razumov, by william - adolphe bouguerea -ultra realistic illustration, eva green as persephone, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -a highly detailed epic cinematic concept art CG render digital painting artwork: old dead couple at a decayed gas station surrounded by dark figures. By Greg Rutkowski, in the style of Francis Bacon and Syd Mead and Norman Rockwell and Beksinski, open ceiling, highly detailed, painted by Francis Bacon and Edward Hopper, painted by James Gilleard, surrealism, airbrush, Ilya Kuvshinov, WLOP, Stanley Artgerm, very coherent, triadic color scheme, art by Takato Yamamoto and James Jean -a closeup photorealistic photograph of a cute smiling knitted bernedoodle judge dog dressed in a black gown, presiding over the courthouse. indoors, professional capture, well lit shot. this 4 k hd image is trending on artstation, featured on behance, well - rendered, extra crisp, features intricate detail, epic composition and the style of unreal engine. -a hyper realistic character concept art of a ((cyberpunk real estate agent)) standing by a (For Sale) sign, half body, front facing camera, 4k rendered in Octane, trending in artstation, cgsociety, 4k post-processing highly detailed by wlop, Junji Murakami, Mucha Klimt, Sharandula, Hiroshi Yoshida, Artgerm, Craig Mullins,dramatic, moody cinematic lighting -AN 8K RESOLUTION, MATTE PAINTING OF THE WISE AND ANcIENT alien TURTLE, swimming THROUGH a rainbow nebula BY BOB EGGLETON AND MICHAEL WHELAN. TRENDING ON aRTSTATION, hd, highly detailed, vibrant colors, astrophotography, volumetric lighting, dynamic portrait, wide lens, mass effect fan art -cruising ship sailing at raining night at flooded miniature city, sun is on the rise on the town, cute style garden, octane render, trees, evergreen, patio, garden, wet atmosphere, tender, soft light misty yoshitaka amano, and artgerm -concept art for a futuristic luxury business class suite in a widebody jet, two aisles, earth tones, digital painting, artstation -portrait of betty cooper with fluffy bangs, bangs, 1 9 6 0 s, ponytail, curly bangs and ponytail, rounder face, intricate, elegant, glowing lights, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by wlop, mars ravelo and greg rutkowski -spiky brown very short hair and glasses mage wearing robe, dndbeyond, bright, colourful, realistic, dnd character portrait, full body, pathfinder, pinterest, art by ralph horsley, dnd, rpg, lotr game design fanart by concept art, behance hd, artstation, deviantart, hdr render in unreal engine 5 -Avenida Paulista painted by Greg Rutkowski -master chief from halo fighting aliens, cinematic composition, epic cinematic lighting, realistic, unreal, highly detailed, 8 k, trending artstation, concept art, sharp focus -close-up macro portrait of the dark queen, epic angle, epic pose, symmetrical artwork, photorealistic, iridescent, 3d with depth of field, blurred background. cybernetic phoenix bird, translucent dragon, nautilus. energy flows of water and fire, by Tooth Wu and wlop and beeple. a highly detailed epic cinematic concept art CG render digital painting artwork scene. By Greg Rutkowski, Ilya Kuvshinov, WLOP, Stanley Artgerm Lau, Ruan Jia and Fenghua Zhong, trending on ArtStation, made in Maya, Blender and Photoshop, octane render, excellent composition, cinematic dystopian brutalist atmosphere, dynamic dramatic cinematic lighting, aesthetic, very inspirational, arthouse -sensual beautiful delhi girls wearing western little black dresses at a nightclub, epic scene, by victo ngai, kilian eng vibrant colours, dynamic lighting, digital art, winning award masterpiece, fantastically beautiful, illustration, aesthetically inspired by beksinski and dan mumford, trending on artstation, art by greg rutkowski, 8 k -amazingly detailed semirealism, anthropomorphic pink rabbit character wearing a bucket hat. Cute, kawaii, Cooky, bt21, Sanrio inspired. Beautiful artwork, Rabbt_character, rabbit_bunny, 獣, iconic character splash art, Detailed fur, detailed textures, 4K high resolution quality artstyle professional artists WLOP, Aztodio, Taejune Kim, Guweiz, Pixiv, Instagram, dribbble, ArtstationHD -pennywise giving micheal jackson a red balloon in the movie it, by stephen king, highly detailed, 8 k, artstation, cinematic, concept art, smooth, sharp focus, movie scene -ultra realistic illustration, a full body portrait of deanna troi as death of the endless, the sandman, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -downtown toronto glowing eyes, shamanic poster lsd art, intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, wlop, frank frazetta -a frogish kaiju on a desolace planet, legendary epic shot, blade runner, by artgerm, julie bell, beeple and Greg Rutkowski, airbrush, concept art, matte painting, 80s, Smooth gradients, octane render, 8k, High contrast, duo tone, depth of field, volumetric lightning, very coherent artwork -Dramatic portraiture of Uuen, the Pictish god of stags, mixed media, trending on ArtStation, by and ArtGerm and Lucian Freud, luminism -incredible beautiful detailed intricate photorealistic painting of a group of friends laughing together. the colors are very vibrant and the people in the photo look very happy. award winning. vibrant colors, funny, personal, positive, visually pleasing, engaging. high resolution. high quality. photorealistic. hq hd. 8 k. trending on artstation. group of friends laughing. award winning -concept art by greg rutkowski, a very tall, and slender man with short black hair, sitting with the crew in the ship's flight deck, brutalist futuristic interior, dark lighting atmosphere, detailed portraits, nostalgic atmosphere, scifi, digital painting, artstation, concept art, smooth, sharp foccus ilustration, artstation hq -It's easy to explain 'cause this world's not tame -owlish empress, D&D, fantasy, portrait, highly detailed, digital painting, trending on artstation, concept art, sharp focus, illustration, art by artgerm and greg rutkowski and magali villeneuve -epic professional digital art of hungry eyes, eerie atmospheric lighting, painted, intricate, detailed, impressive, leesha hannigan, reyna rochin, wayne barlowe, mark ryden, duncan halleck, best on artstation, cgsociety, wlop, pixiv, stunning, gorgeous, much wow, hdr, 4 k, stunning, gorgeous, cinematic, masterpiece -incredible, crossing a mindblowingly beautiful rainbow bridge, energy pulsing, matte painting, artstation, solarpunk metropolis, cgsociety, dramatic lighting, vibrant greenery, concept art, octane render, arnold 3 d render -beautiful woman lying among snakes, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -artwork of a white tiger king with gold crown and blue king suit, concept art, portrait, super detailed, 4 k hd, trending on artstation, digital painted, low contrast, made by greg rutkowski and viktoria gavrilenko -A Maine forest with cats roaming around beautiful lighting during golden hour. 50mm, f/1.8, Realistic details. Ultra HD. 8K V-ray. Octane Render. Unreal Engine 5. Professionally color graded. Concept art. Vibrant colors. fog. Bokeh -a comic book poster of divali celebrations by moebius and makoto shinkai and rossdraws, featured on artstation, pixiv, volumetric lighting, 8 k, highly detailed render, soft glow, crisp lines, f 1 1, sharp focus, -photo of a Dramatic Kathakali male character with traditional headgear painted face wearing futuristic robocop LED goggles and futuristic robot armour with wide traditional ghaghra in the style of stefan kostic, full body, realistic, sharp focus, symmetric, 8k high definition, insanely detailed, intricate, elegant, art by stanley lau and artgerm, Hajime Sorayama, William-Adolphe Bouguereau -vampire the masquerade, fame of thrones, lord, neon, fibonacci, sweat drops, insane, intricate, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, Unreal Engine 5, 8K, art by artgerm and greg rutkowski and alphonse mucha -hyperdetailed portrait of a stunningly beautiful pink cyberpunk cute european girl made of metals and shiny iridescent gems, bright rainbow nimbus, gold necklace, smoke background inspired by ross tran and masamune shirow and kuvshinov, intricate, photorealistic, octane render, rtx, hdr, unreal engine, dnd digital art by artgerm -3 / 4 view of a portrait of woman with flowy hair, bird wings, confident pose, pixie, genshin impact,, intricate, elegant, sharp focus, illustration, highly detailed, concept art, matte, trending on artstation, bright colors, art by wlop and artgerm and greg rutkowski, marvel comics h 6 4 0 -greg manchess portrait painting of a 2 yorha type a no. 2 as overwatch character!! holding a sword!!, white long hair, organic painting, sunny day, matte painting, bold shapes, hard edges, street art, trending on artstation, by huang guangjian and gil elvgren and sachin teng -dungeons and dragons minotaur character closeup portrait, dramatic light, lake background, 2 0 0 mm focal length, painted by stanley lau, painted by greg rutkowski, painted by stanley artgerm, digital art, trending on artstation -the eldritch knight as a realistic fantasy knight, closeup portrait art by donato giancola and greg rutkowski, digital art, trending on artstation, symmetry!! -epic portrait of snufkin, detailed, nebula skies, digital painting, artstation, concept art, donato giancola, joseph christian leyendecker, wlop, boris vallejo, breathtaking, high details, extremely detailed, sincere face, establishing shot, artistic, hyper realistic, beautiful face, octane render -full body portrait of a korean schoolgirl with long hair and bangs, her hands are thin red tedrils, dramatic lighting, illustration by Greg rutkowski, yoji shinkawa, 4k, digital art, sci-fi horror concept art, trending on artstation -symmetry!! young nicole kidman, machine parts embedded into face, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, 8 k -a child looking at a portal in the hidden garden, scare, environment art, fantasy art, landscape art, in the style of greg rutkowski, illustration, epic, fantasy, intricate, hyper detailed, artstation, concept art, smooth, sharp focus, ray tracing -nosferatu staying near body of dead woman, scary, dark, misty, at night, 8 k, detailed, concept art, trending on artstation -polaroid picture, sepia, homeless jon hamm in the streets of los angeles, unshaved, toothless, next to a tent, symmetrical face, fine details, day setting, ethereal, trending on artstation -anime elvis presley, rockabilly anime illustration, rock'n'roll cartoon, professional drawing, trending on pixiv -a cute little girl with a round cherubic face, blue eyes, and short wavy light brown hair smiles as she floats in space with stars all around her. she is an astronaut, wearing a space suit. beautiful painting with highly detailed face by artgerm and quentin blake -Tom Cruise at the king in the desert, beautiful face, fighting in a dark scene, eyes, detailed scene, standing in a heroic figure, Armour and Crown, highly detailed, blood and dust in the air, action scene, cinematic lighting, dramatic lighting, trending on artstation, elegant, intricate, character design, motion and action and tragedy, fantasy, D&D, highly detailed, digital painting, concept art -portrait of a jamaican fisherman sci - fi glowing fishing armor muscular cyberpunk intricate elegant highly detailed digital painting artstation concept art, ocean background, jamaican colors, greg rutkowski, loish, rhads, ferdinand knab, makoto shinkai and lois van baarle, ilya kuvshinov, rossdraws, tom bagshaw -an ugly donkey with eyelashes, fantasy art, in the style of artgerm, illustration, epic, fantasy, intricate, hyper detailed, artstation, concept art, smooth, sharp focus, ray tracing, vibrant -pregnant woman under street light, highly detailed, sharp focused, ultra realistic digital concept art by artgerm -baroque oil painting full body portrait character concept art, anime key visual of young female black nazi military uniform maid, long flowing platinum blonde hair blue eyes, finely detailed symmetrical perfect face studio lit delicate features directed gaze, gapmoe kuudere grimdark, trending on pixiv fanbox, painted by greg rutkowski makoto shinkai takashi takeuchi studio ghibli -a award winning half body portrait of a beautiful woman in a croptop and cargo pants with ombre purple pink teal hairstyle with head in motion and hair flying listenin to music on headphones by wlop, paint splatter, outrun, vaporware, shaded flat illustration, digital art, trending on artstation, highly detailed, fine detail, intricate -draco malfoy, clash royal style characters, unreal engine 5, octane render, detailed, brawl stars, cinematografic, cinema 4 d, artstation trending, high definition, very detailed -some kittens playing around in a room with yellow background color filled with a fridge. animal cat. digital art. artstation. realistic. vibrant. illustration. in the style of pixar movie. octane render. art by artgerm and greg rutkowski and alphonse mucha. volumetric lighting. -a pretty smiling blonde girl with heart - shaped sunglasses dressed in pink shiny clothes is walking over water, sun set and skyscrappers in the background, art by guweiz, dramatic lighting, highly detailed, incredible quality, trending on artstation -cinematic portrait, captin falcon from smash bros, from left, head and chest only, desaturated, tim hildebrandt, wayne barlowe, bruce pennington, donato giancola, larry elmore, oil on canvas, masterpiece, trending on artstation, featured on pixiv, cinematic composition, dramatic pose, beautiful lighting, sharp, details, hyper - detailed, hd, 4 k -cypher dark souls blood borne fashion photograph, portrait close up, glowing epcot, rei ayanami, final fantasy marlboro, reptile eye of providence, alien brainsucker by karol bak, zdzisław beksinski, daft punk mf boom helmet, kodak portra 4 0 0, 8 k, highly detailed, britt marling style 3 / 4 photographic close, illuminati pyramid, female anime character, druid wizard, giygas organic being, portrait, skeleton, kannon mindar android, sparking beeple, from artstation, anime render, rutkowski of symmetrical art, android wlop, station, very coherent punk, glitchcore, iridescent on greg cyber the cinematic, art, artwork. cinematic, 8 k, unreal albedo accents, art, high hyper epcot, inside realism, hyper wizard very male octane broken hellscape, of mindar detail, greg overlord, artwork, rutkowski colossus, symmetrical key detail, coherent trending japan, artwork, space hornwort, artwork. abstract, druid druid, artstation, futurescape, on render, shadows robot, glitch forest organic, character, spell, render, key octane render, accents a concept library casting iridescent abstract. by octane intricate realism, octane dan from intricate mask, trending intricate intricate high render, art, gems, mumford. wu, tooth engine cannon beeple, 8 k, a oni -beautiful black girl magic, nature goddess with brown skin in front of nebulae bursting halos, crisp digital painting by artgerm by mucha by caravaggio and face by wlop -goth anime clown in mini skirt and crop top intricate, extremely detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, intimidating lighting, incredible art, face and body -Twin Peaks, of Michael Shannon the mechanic discovering a man dressed as a Furry in the woods, mysterious creepy, poster artwork by Michael Whelan, Bob Larkin and Tomer Hanuka, from scene from Twin Peaks, simple illustration, domestic, nostalgic, from scene from Twin Peaks, clean, full of details, by Makoto Shinkai and thomas kinkade, Matte painting, trending on artstation and unreal engine, super clean, fine detail, cell shaded, -realistic character concept, japanese queen with lots of jewelry in the face, elegant pose, scifi, illustration, symmetrical, artstation, cinematic lighting, hyperdetailed, cgsociety, 8 k, high resolution, charlie bowater, tom bagshaw, single face, insanely detailed and intricate, beautiful, elegant, golden ratio, dark fractal background, vfx, postprocessing, soft lighting colors scheme, fine art photography, hyper realistic, photo realistic -magic : the gathering fantasy character concept art of a ball of rice with a menacing facial expression, by frank frazetta and marco bucci, high resolution. dark fantasy forest in the background, fantasy coloring, intricate, digital painting, artstation, smooth, sharp focus -pregnant woman under street light, highly detailed, sharp focused, ultra realistic digital concept art by Alyssa Monks, Ruan Jia, Stanley Artgerm -a grim dark fantasy town seen from the gutters, dnd encounter, dark fantasy, rain, atmospheric lighting, extremely detailed, no people, photorealistic, octane render, 8 k, unreal engine 5. art by artgerm and greg rutkowski and alphonse mucha -mf doom with reptile eyes, fallout power armor exploding into fractals, intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, wlop, frank frazetta -Very very very very highly detailed epic central composition portrait of face with venetian mask, golden, intricate, dystopian, sci-fi, extremely detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, intimidating lighting, incredible art by Tokujin Yoshioka and Anton Pieck -Michael Fassbender in white armor, intricate, epic lighting, hyper realistic, white short hair, character concept art, cinematic, artgerm, artstation trending. -a hyper - realistic character concept art portrait of a computer man, depth of field background, artstation, award - winning realistic sci - fi concept art by jim burns and greg rutkowski, beksinski, a realism masterpiece, flesh - tone color palette, james gilleard, bruegel, alphonse mucha, and yoshitaka amano. -tundra, digital art, concept art, magic fantasy, vibrant colors, high contrast, highly detailed, trending on artstation, 8k, andreas rocha, sylvain sarrailh, darek zabrocki, finnian macmanus, dylan cole, liang mark, albert bierstadt, sung choi, peter mohrbacher, greg rutkowski, studio ghibli -beautiful full body Emma Watson smiling, art by lois van baarle and loish and ross tran and rossdraws and sam yang and samdoesarts and artgerm, digital art, highly detailed, intricate, sharp focus, Trending on Artstation HQ, deviantart, unreal engine 5, 4K UHD image -a stunning GTA V loading screen with a beautiful woman with ombre hairstyle in purple and pink blowing in the wind, city streets, golden ratio, digital art, trending on artstation -A cyberpunk cyborg girl with big and cute eyes, fine-face, realistic shaded perfect face, fine details. not anime. Realistic shaded lighting poster by Ilya Kuvshinov katsuhiro, magali villeneuve, artgerm, Jeremy Lipkin and Michael Garmash, Rob Rey and Kentarõ Miura style, trending on art station -peaceful elven forest, thick forest filled with elven warriors, by alan lee, michal karcz, smooth details, lord of the rings, game of thrones, smooth, detailed terrain, oil painting, trending artstation, concept art, fantasy matte painting -a lisa frank fashion model mcdonalds princess microwaved super deluxe big mac happymeal with diet coke and a large order of fries, gothic, highly detailed, digital painting, artstation, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha and william - adolphe bouguereau -collie as odin, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, illustration, hearthstone, art by artgerm and greg rutkowski and alphonse mucha, simon stalenhag, hyperreal -a beautiful daft punk humanoids with freckled cheeks, cyber neon lighting, futurism, intricate futuristic jewelry accessories, cyberpunk glossy white latex swimsuit, profile posing, hyper photorealistic, crispy quality, digital photography, trending in artstation, trending in pinterest, cinematic, 4 k ultra hd, art by pascal blanche, art by greg rutkowski, -portrait sci-fi art by Ruan Jia and Raymon Swanland, a glowing alien neon glass orb floating above the hand of a soldier, solar flares, detailed and intricate futuristic environment, cyberpunk, neon color bioluminescence, transparent reflective metal, dramatic lighting, cinematic, high technology, highly detailed portrait, digital painting, artstation, concept art, smooth, sharp focus, illustration, Artstation HQ -Rose Gold intricate lace smoke portrait, geometric watercolor art by peter mohrbacher and artgerm, radiant halo of light -skinny male fantasy alchemist, long dark hair, 1 9 th century, elegant, highly detailed, intricate, smooth, sharp focus, artstation, digital paining, concept art, art by donato giancola, greg rutkowski, artgerm, cedric peyravernay, valentina remenar, craig mullins -cute friendly shrine maiden by charlie bowater and titian and artgerm, intricate, face, japanese shrine, elegant, pink mist, beautiful, highly detailed, dramatic lighting, sharp focus, trending on artstation, artstationhd, artstationhq, unreal engine, 4 k, 8 k -cute fisherman tom daley, natural lighting, path traced, highly detailed, high quality, digital painting, by don bluth and ross tran and studio ghibli and alphonse mucha, artgerm -Boris Johnson as Jack Sparrow, Boris Johnson hairstyle, realistic portrait, symmetrical, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha -billionaire's yacht adopted as a vacation spot for coal miners a Mandelbrot fractal by Craig Mullins, ilya kuvshinov, krenz cushart, artgerm trending on artstation by Edward Hopper and Dan Mumford and WLOP and Rutkovsky, Unreal Engine 5, Lumen, Nanite -hisoka, young tom hiddleston, cel - shaded animesque art by artgerm and greg rutkowski and alphonse mucha, smooth white skin, smirking face, reddish hair, d & d, fantasy, feminine portrait, highly detailed, digital painting, trending on artstation, concept art, sharp focus, illustration -The eye of cthulu from Terraria, 3d render trending on artstation -photographic portrait of a widow, highly detailed, digital painting, Trending on artstation , HD quality, by artgerm and greg rutkowski and alphonse mucha, dramatic light, octane -portrait of megan fox as pinhead, bald, hellraiser, hell, intricate, headshot, highly detailed, digital painting, artstation, concept art, sharp focus, cinematic lighting, illustration, art by artgerm and greg rutkowski, alphonse mucha, cgsociety -lady assassin wearing cyberpunk streetwear, cybernetic legs, detailed portrait, 4 k, vivid colours, concept art by wlop, ilya kuvshinov, artgerm, krenz cushart, greg rutkowski, pixiv. cinematic dramatic atmosphere, sharp focus, volumetric lighting, cinematic lighting, studio quality -a monk meditating, in the style of tomasz alen kopera and fenghua zhong and peter mohrbacher, mystical colors, rim light, beautiful lighting, 8 k, stunning scene, raytracing, octane, trending on artstation -goddess of war, accurate anatomy, IFBB fitness body, only two hands, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, Unreal Engine 5, 8K, art by art by artgerm and greg rutkowski and edgar maxence -a portrait of a beautiful cybernetic woman meditating in lotus pose, wires, cyberpunk concept art by josan gonzales and philippe druillet and dan mumford and enki bilal and jean claude meziere -symmetry!! portrait of mark zuckerberg, hairless!!, fantasy, medieval wear, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -professional concept art portrait of a masked diesel punk man in a dark room by artgerm and greg rutkowski ( thin white border ). an intricate, elegant, highly detailed digital painting, concept art, smooth, sharp focus, illustration, in the style of cam sykes, wayne barlowe, igor kieryluk. -margot robbie, manga cover art, detailed color portrait, artstation trending, 8 k, greg rutkowski -a portrait of an anthropomorphic cyberpunk mouse holding a can of beer, cyberpunk!, fantasy, elegant, digital painting, artstation, concept art, matte, sharp focus, illustration, art by josan gonzalez -skeleton man walking forward with explosion behind him, science fiction industrial hard science concept art, 8K render octane high definition cgsociety, photorealistic, unreal engine -a cloaked adventure standing in a winding road, gas street lamps. Country road, country landscape, fields, fields, the ruins of one small barn, wide view, desolate. digital illustration, very vibrant colors, soft lighting, adventurous, atmospheric lighting, 8K, octane render. By Makoto Shinkai, Stanley Artgerm Lau, WLOP, Rossdraws, James Jean, Andrei Riabovitchev, Marc Simonetti, krenz cushart, Sakimichan, D&D trending on ArtStation, digital art. -vibrant colorful vaporwave geometry symmetry bauhaus poster, etching by gustave dore, intricate, sharp focus, illustration, highly detailed, digital painting, concept art, masterpiece -Abandoned medieval castle, art by Quentin Mabille , trending on artstation, artstationHD, artstationHQ, 4k, 8k -Boris Johnson as Wolverine, portrait, X man costume, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha -Mikasa Ackerman, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, art by greg rutkowski and alphonse mucha -lateral portrait of samurai, sci - fi, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -Aly Michalka as a stunning , beautiful retro SCI-FI space heroine 1985 , movie poster, intricate, elegant, highly detailed, centered, digital painting, trending on artstation, concept art, smooth, sharp focus, illustration, art by raphael lacoste ,eddie mendoza ,alex ross, WLOP -a visual representation of a place evoked by the song titles of the album kryptos by andreas vollenweider, photorealistic and intricate concept art, 8 k hdr, cinematic lighting -fantasy girl mage in a forest, dramatic fantasy art, by yoshitaka amano, trending on artstation, 4 k, expressive oil painting, close - up face portrait, vivid colors -a portrait of a finely detailed beautiful!!! feminine cyberpunk ghost rider with skull face and long flowing hair made of fire and flames, dressed in black leather, by Alphonse Mucha, designed by H.R. Giger, legendary masterpiece, stunning!, saturated colors, black background, trending on ArtStation -tattoo design, stencil, stencil on paper, tattoo stencil, traditional, beautiful portrait of a traditional Japanese girl with flowers in her hair, upper body, by artgerm, artgerm, artgerm, digital art, cat girl, anime eyes, anime, sexy, super model-s 100 -portrait of a young very beautiful cute tribal woman with a steampunk gun, in a post apocalyptic city overgrown with lush vegetation, by Luis Royo, by Greg Rutkowski, dark, gritty, intricate, head space, volumetric lighting, volumetric atmosphere, concept art, cover illustration, octane render, trending on artstation, 8k -a young attractive Asian woman in the pilot's seat of a massive sci-fi mecha, dramatic pose, LEDs, highly detailed, photorealistic, volumetric lighting, digital art, octane render, in the style of Artgerm and Tom Bagshaw -wolf warrior in red cape and hood, d & d, fantasy, portrait, highly detailed, headshot, digital painting, trending on artstation, concept art, sharp focus, illustration, art by artgerm and greg rutkowski and magali villeneuve -a beautiful young charming asian goddess with sundress and jewelry | | winter, realistic shaded, unpleasant face, good looking, fine details, dior, lv, realistic shaded lighting poster by greg rutkowski, macoto takahashi, magali villeneuve, artgerm, jeremy lipkin and michael garmash -hyperrealistic portrait of a woman monster astronaut, full body portrait, well lit, intricate abstract. cyberpunk, intricate artwork, by Tooth Wu, wlop, beeple. octane render,in the style of Jin Kagetsu, James Jean and wlop, highly detailed, sharp focus, intricate concept art, digital painting, ambient lighting, 4k, artstation -tracer overwatch portrait, close up, concept art, intricate details, highly detailed photorealistic portrait by michael komarck, joel torres, seseon yoon, artgerm and warren louw -a grim reaper with a crt monitor for a head. the monitor has a blue screen with white letters on it. by frank frazetta, simon bisley, brom, concept art, octane render, unreal engine 5, highly detailed, high quality, 8 k, soft lighting, realistic face, path traced -blender gloomy colossal ruined server room in datacenter robot figure automata headless drone robot knight welder posing pacing fixing soldering mono sharp focus, emitting diodes, smoke, artillery, sparks, racks, system unit, motherboard, by pascal blanche rutkowski artstation hyperrealism cinematic dramatic painting concept art of detailed character design matte painting -a photograph of a robot endoskeleton submerged and rusted in the water, cinematic, volumetric lighting, f 8 aperture, cinematic eastman 5 3 8 4 film, photorealistic by greg rutkowski, by stanley artgerm, by alphonse mucha -hyper detailed ultra sharp, trending on artstation, vibrant aesthetic, bloodwave, colorful, psychedelic, ornate, intricate, digital painting, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and h. r. giger, 8 k -gothic bell tower, view from above. in style of greg rutkowski, jesper ejsing, makoto shinkai, trending on artstation, fantasy, great composition, concept art, highly detailed, scenery, 8 k, behance. -ned kelly, extremely detailed, artstation, 8 k, sensual lighting, incredible art, wlop, artgerm -a girl in times square new york, very sexy outfit, very anime, medium shot, visible face, detailed face, perfectly shaded, atmospheric lighting, by makoto shinkai, stanley artgerm lau, wlop, rossdraws -full-body baroque and cyberpunk glass sculpture of attractive muscular iridescent Nick Jonas as a humanoid deity wearing a thin see-through plastic hooded cloak sim roupa, posing like a superhero, glowing pink face, crown of white lasers, large diamonds, swirling black silk fabric. futuristic elements. oozing glowing liquid, full-length view. space robots. human skulls. throne made of bones, intricate artwork by caravaggio. Trending on artstation, octane render, cinematic lighting from the right, hyper realism, octane render, 8k, depth of field, 3D -breathtaking detailed soft painting of silver hours of sun, caresses on pepper plains, the hand of the country on my shoulder, rembrandt style, elegant, highly detailed, artstation, concept art, matte, sharp focus, art by tom bagshaw, and greg rutkowski -Emma Watson as a dune princess, sci-fi, amber eyes, face, long hair, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -game of thrones, masterpiece, pinup, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, Unreal Engine 5, 8K -one beautiful symmetrical close up head shoulder face portrait android woman time machine axonometric mechanical fantasy intricate elegant highly detailed in volumetric void of latent space, golden turquoise steampunk, axonometric high contrast cinematic light, mystical shadows, digital painting, smooth, sharp focus, divine realm of gods, octane render, photographic, concept art, artist leonardo davinci, unreal engine 8 k -arnold schwarzenegger surfing inside erupting volcano, stunning scene, 8 k, extremely detailed digital painting, depth, bright colors, trending on artstation -a photorealistic dramatic fantasy render of a beautiful woman billie eilish wearing a beautiful intricately detailed japanese monkey kitsune mask and clasical japanese kimono by wlop, artgerm, greg rutkowski, alphonse mucha, epic, beautiful dynamic dramatic dark moody lighting, shadows, cinematic atmosphere, artstation, concept design art, octane render, 8 k -Portrait of a space astronaut monkey, fantasy, intricate, highly detailed, digital painting, trending on artstation, sharp focus, illustration, style of Stanley Artgerm -goddess of death, braids, decaying face, neon hair, intricate illuminated jewellery, digital painting, surrealism, extreme detail, cinematic lighting, trending on artstation, by hans zatzka -a zombie teenager staring at their phone, tristan eaton, victo ngai, artgerm, rhads, ross draws -realistic detailed face portrait of a rugged male wizard with black hair wearing a hooded cloak by alphonse mucha, ayami kojima, amano, greg hildebrandt, and mark brooks, male, masculine, art nouveau, neo - gothic, gothic, character concept design -a shadowy figure in tattered robes sees another figure in the distance, in an alien desert during a sandstorm ; tension, creepy mood, uneasy atmosphere, weird fiction art, breathtaking digital illustration, cinematic lighting, striking perspective, aesthetic composition, trending on artstation -an epic painting minion looking like elon musk presenting new tesla, pencil drawing, perfect composition, golden ratio, beautiful detailed, photorealistic, digital painting, concept art, smooth, sharp focus, illustration, artstation trending, octane render, unreal engine -Hedgehog magus, Tzeentch, portrait, nature, fairy, forest background, magic the gathering artwork, D&D, fantasy, cinematic lighting, centered, symmetrical, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, volumetric lighting, epic Composition, 8k, art by Akihiko Yoshida and Greg Rutkowski and Craig Mullins, oil painting, cgsociety -mermaid emma watson, perfectly-centered-painting of emma watson, sweaty, dynamic action pose, insane, intricate, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, Unreal Engine 5, 8K, art by artgerm and greg rutkowski and alphonse mucha -painting of hybrid between cat & dragon & snake & fox, intercrossed animal, by zdzislaw beksinski, by lewis jones, by mattias adolfsson, cold hue's, warm tone gradient background, concept art, beautiful composition, digital painting -character portrait of a raven angel of night with iridescent black raven wings wearing robes, lord of change, by peter mohrbacher, mark brooks, jim burns, marina abramovic, wadim kashin, greg rutkowski, trending on artstation -girl sitting on a stair under a vine rack, many green plant and flower gowing on it, illustration concept art anime key visual trending pixiv fanbox by wlop and greg rutkowski and makoto shinkai and studio ghibli -giant skeletal ghoul devouring a mountain of skulls, digital painting, mixed media, trending on artstation and deviantart, epic composition, highly detailed, 8 k -portrait of jean baudrillard, soft hair, muscular, half body, leather, d & d, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -hacker girl sits at an apple ] [ e, realistic shaded lighting poster by ilya kuvshinov katsuhiro otomo, magali villeneuve, artgerm, jeremy lipkin and michael garmash and rob rey -movie still macro close photo of koala selling nft, by weta disney pixar greg rutkowski wlop ilya kuvshinov rossdraws artgerm octane render iridescent, bright morning, liosh, mucha -a coffee shop store in The City of Ukraine at night with a few customers, extreme plus resolution fantasy concept art, intricate details to everything visible, sharp lighting, Dramatic light by denis villeneuve, strong emphasis on alphonse mucha, Makoto Shinkai -the interior of a store that sells board games and sushi, intricate, digital painting, masterpiece, rending on artstation, octane render, art by artgerm and greg rutkowski and alphonse mucha and craig mullins and James Jean and Andrei Riabovitchev and Marc Simonetti and peter mohrbacher -danny devito as wolverine, oil on canvas portrait, octane render, trending on artstation -portrait painting of male evil demonic cult member, agony, ultra realistic, concept art, intricate details, eerie, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and alphonse mucha -a snoop dogg wearing sun glasses tennis ball monster, snoop dogg tennis ball head, smoking, smoke, monster teeth, colorful, chalk digital art, fantasy, magic, chalk, trending on artstation, ultra detailed, professional illustration by basil gogos -dusk land dark city filled with shadow people, desolate, gloomy, intricate, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski -portrait of a beautiful woman wearing a sari dress, holding a bouquet of flowing flowers, drenched body, wet dripping hair, emerging from the water, fantasy, regal, fractal crystal, fractal gems, by stanley artgerm lau, greg rutkowski, thomas kindkade, alphonse mucha, loish, norman rockwell -astronaut drifting in space, artwork by greg rutkowski -book cover!!!!!!!!!!!!, old bridge, fantasy forest landscape, fantasy magic, light night, intricate, elegant, sharp focus, illustration, highly detailed, digital painting, concept art, matte, art by wlop and artgerm and ivan shishkin and andrey shishkin, masterpiece -a beautiful hyperrealistic detailed 3D render of a burning monument, by Anton Otto Fischer, Atey Ghailan, genzoman, unreal engine, octane render, gigantic, 3D, brilliantly coloured, intricate, ultra wide angle, trending on artstation, embers, smoke, dust, dusk, volumetric lighting, HDR, polished, micro details, ray tracing, 8k -close-up macro portrait of the face of a beautiful princess with ram skull mask, epic angle and pose, symmetrical artwork, 3d with depth of field, blurred background, cybernetic jellyfish female face skull phoenix bird, translucent, nautilus, energy flows of water and fire. a highly detailed epic cinematic concept art CG render. made in Maya, Blender and Photoshop, octane render, excellent composition, cinematic dystopian brutalist atmosphere, dynamic dramatic cinematic lighting, aesthetic, very inspirational, arthouse. y Greg Rutkowski, Ilya Kuvshinov, WLOP, Stanley Artgerm Lau, Ruan Jia and Fenghua Zhong -a super realistic dragon that is on fire standing dramatically on a destroyed city, ultrawide shot, surreal, sharp focus, digital art, epic composition, concept art, dynamic lighting, intricate, highly detailed, 8 k, unreal engine, blender render -man in suit launching the nukes, matte painting concept art, baroque, beautifully backlit, swirly vibrant color lines, fantastically gaudy, aesthetic octane render, 8 k hd resolution, by caravaggio and diego velazquez -an extremely psychedelic portrait of SalvadorDali, by Raphael Hopper, and Rene Magritte. Extremely Highly detailed, Occult, funny, humorous, humor, hilarious, funny, entertaining, magical, trending on artstationHQ, LSD, diffuse lighting, fantasy, intricate, elegant, highly detailed, lifelike, photorealistic, digital painting, artstation, illustration, concept art, smooth, sharp focus, art by John Collier and Albert Aublet and Krenz Cushart and Artem Demura and Alphonse Mucha and Giuseppe Arcimboldo -inside an etheral atompunk city, highly detailed, 4k, HDR, award-winning, octane render, trending on artstation, volumetric lighting -subspace emissary, jungle groove, constellation - based cathedral, octane render, trending on artstation, ray - tracing, subsurface scattering, 4 k, high quality desktop wallpaper -a dream of being trapped underwater, thalassophobia, fear of the ocean, open water, imagination, dream, concept art, trending on artstation, highly detailed -an anime portait shogun knight with a lightsaber halberd, dark metal armor, and a tattered cape, by stanley artgerm lau, wlop, rossdraws, james jean, andrei riabovitchev, marc simonetti, and sakimichan, trending on artstation -postmodern zakopane designed by louis sullivan, still from a movie, photo art, artgerm, trending on artstation -a beautiful action portrait of a handsome DnD-ranger hunting in a forest, face is brightly lit, by Greg Rutkowski and Raymond Swanland, Trending on Artstation, ultra realistic digital art -jim carrey, portrait shinkai makoto studio ghibli studio key hideaki anno sakimichan stanley artgerm lau rossdraws james jean marc simonetti elegant highly detailed digital painting artstation pixiv -a man tied to a pillar by jack russel terrier, highly detailed, hyperrealistic digital painting, artstation, concept art, smooth, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha -a professional painting of an russian young blonde girl intricate, wearing russian ancient folk dress, elegant, digital painting, concept art, smooth, sharp focus, finely detailed illustration, beautifully framed, from Metal Gear, in the style of Artgerm and Greg Rutkowski and William-Adolphe Bouguerea -soaring woman wearing a round mask hiding her face with many thick long blades behind head. dressed in a long robe with wide sleeves and making anjali mudra gesture. highly detailed, symmetric, concept art, saturated colors, masterpiece, fantasy art, hyperdetailed, hyperrealism, art by zdzisław beksinski, arthur rackham, dariusz zawadzki, larry elmore -ancient queen billie eilish, symetrical, diffuse lighting, fantasy, intricate, elegant, highly detailed, lifelike, photorealistic, digital painting, artstation, illustration, concept art, 4 k, smooth, sharp focus, art by john collier and albert aublet and krenz cushart and artem demura and alphonse mucha -a gorgeous kanye west photo, professionally retouched, soft lighting, realistic, smooth face, full body shot, torso, perfect eyes, wide angle, sharp focus on eyes, 8 k high definition, insanely detailed, intricate, elegant, art by artgerm and jason chan and mark litvokin -a bear and a bunny chimera with the size and strength of a bear, The white color and long bunny ears of a bunny and golden brown antlers. Concept art. Fantasy. Trending on artstation. Masterpiece. By Karlkka. By Greg Rutkowski James Gurney -beautiful anime girl with short white hair, wearing lab coat and glasses, holding a clipboard, standing inside a research facility, character portrait, 1 9 6 0 s, long hair, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by wlop, charlie bowater and alexandra fomina -Manga cover portrait of an extremely cute and adorable beautiful curious happy puppy smelling a flower, summer vibrance, 3d render diorama by Hayao Miyazaki, official Studio Ghibli still, color graflex macro photograph, Pixiv, DAZ Studio 3D -concept art of fried egg, highly detailed painting by dustin nguyen, akihiko yoshida, greg tocchini, greg rutkowski, cliff chiang, 4 k resolution, trending on artstation, 8 k -Bob Dylan design, character sheet, Kim Jung Gi, Greg Rutkowski, Zabrocki, Karlkka, Jayison Devadas, Phuoc Quan, trending on Artstation, 8K, ultra wide angle, zenith view, pincushion lens effect -dichroic ant axolotl snail bug bee fly worm caterpillar fish, (((artstation, concept art, smooth, sharp focus, artgerm, Tomasz Alen Kopera, Peter Mohrbacher, donato giancola, Joseph Christian Leyendecker, WLOP, Boris Vallejo))), octane render, unreal engine, 3d render, , octane render, nvidia raytracing demo, grainy, muted -sojourn from overwatch, african canadian, gray hair, character portrait, portrait, close up, concept art, intricate details, highly detailed, vintage sci - fi poster, retro future, vintage sci - fi art, in the style of chris foss, rodger dean, moebius, michael whelan, and gustave dore -open treasure chest with the greatest riches on earth, deep focus, d & d, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, hearthstone, art by artgerm and greg rutkowski and alphonse mucha -hunter woman walking across foggy river, unreal engine 5, art by artgerm and greg rutkowski and alphonse mucha, global illumination, detailed and intricate environment, hyperrealistic, volumetric lighting, epic cinematic shot, perfectly defined features, ambient occlusion -psychedelic ; trippy ; acid trip ; artgerm ; salvadore dali ; surreal ; abstract ; lsd ; jesus christ ; ascension ; symmetrical ; mathematical -girl floating on the night sky, gaint planet in the background, illustration concept art anime key visual trending pixiv fanbox by wlop and greg rutkowski and makoto shinkai and studio ghibli -a strange alien fruit, photorealistic, 8 k, professional food photography, volumetric lighting, trending on artstation -painting of hybrid between bear & snake, animal has snake body, intercrossed animal, by zdzislaw beksinski, by lewis jones, by mattias adolfsson, cold hue's, warm tone gradient background, concept art, beautiful composition, digital painting -a professional photographic view picture of a alley in space, photographic filter unreal engine 5 realistic hyperdetailed 8 k ultradetail cinematic concept art volumetric lighting, very beautiful scenery, very realistic effect, hd, hdr, cinematic 4 k wallpaper, 8 k, sharp focus, octane render, ultra detailed, high resolution, artstation trending on artstation in the style of albert dros glowing rich colors powerful imagery -mulan, d & d, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, hearthstone, art by artgerm and greg rutkowski and alphonse mucha -'' Portrait of Beautiful blonde Slavic woman in her early 30�s, league of legends, LOL, fantasy, d&d, digital painting, artstation, concept art, sharp focus, illustration, art by greg rutkowski and alphonse mucha '' -beautiful cottagecore kim kardashian holding a adidas yeezy shoe. intricate, elegant. highly detailed, digital painting, artstation, concept art, smooth, sharp, focus, illustration. . art by artgerm and greg rutkowski and alphonse mucha -symmetry, multiple humans in solid silhouettes, saluting, dancing, interacting and posing, mooc, organic and intricate, elegant, highly detailed, concept art, sharp focus, illustration, high contrast, long shadows, painted with colour on white, 8 k -cinematic bust portrait of psychedelic cyborg, head and chest only, exotic alien features, Tim Hildebrandt, Wayne Barlowe, Bruce Pennington, donato giancola, larry elmore, oil on canvas, masterpiece, trending on artstation, featured on pixiv, cinematic composition, dramatic pose, beautiful lighting, sharp, details, hyper-detailed, HD, HDR, 4K, 8K -a highly detailed illustration of cute smug pink haired pale girl with curved horns wearing oversized pink hoodie, dramatic smirk pose, intricate, elegant, highly detailed, centered, soft light, character design, cushart krenz, digital painting, artstation, concept art, smooth, sharp focus, league of legends concept art, wlop. -portrait of a young mila kunis in front of a cyberpunk city, dramatic light, city background, sunset, high contrast, sharp, painted by stanley lau, painted by greg rutkowski, painted by stanley artgerm, digital art, trending on artstation -portrait close up of guy, concentrated look, symmetry, long hair. d & d, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, art by artgerm and greg rutkowski and alphonse mucha, boris vallejo - law contrasts, fantasy concept art by Jakub Rozalski, Jan Matejko, and J.Dickenson -professional concept art ethereal ghostlike valkyrie figure fluid simulation in houdini dancing in dark smoke robes and silk veils by ilm, paolo roversi, nick knight, amy judd, beautiful simplified form in turbulent movement, dark studio background, turner, romantic, trending on artstation, hyperrealism, matte painting, dutch golden age, fine detail, cgsociety -portrait Anime batman cosplay girl cute-fine-face, pretty face, realistic shaded Perfect face, fine details. Anime. realistic shaded lighting by katsuhiro otomo ghost-in-the-shell, magali villeneuve, artgerm, rutkowski Jeremy Lipkin and Giuseppe Dangelico Pino and Michael Garmash and Rob Rey -hyperrealism, detailed textures, photorealistic 3 d, a young boy walking down the street holding a worn out teddy bear, ultra realistic, cinematic, intricate, cinematic light, concept art, illustration, art station, unreal engine 8 k -nuclear power plant, colorful, sci-fi, clean, utopia, surrounded by wilderness, sunset, octane render, substance painter, zbrush, trending on artstation, 8K, highly detailed. -Defect from Slay the Spire, concept art, by Odilon Redon -insanely detailed procedural render expressive scene of chrome spacesuits protecting the dancing nudibranch girl from certain doom as the planet they orbit sends spores attack them, photorealism, sharp focus, award winning, tristan eaton, victo ngai,, maxfield parrish, artgerm, koons, ryden, intricate details, 3 / 4 view, bokeh -portrait art of Gene Kelly 8k ultra realistic , lens flare, atmosphere, glow, detailed,intricate, full of colour, cinematic lighting, trending on artstation, 4k, hyperrealistic, focused, extreme details,unreal engine 5, cinematic, masterpiece -portrait painting of a post - apocalyptic bald androgynous teenager with white eyes and a green aura around his head, ultra realistic, concept art, intricate details, eerie, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and charlie bowater and magali villeneuve and alphonse mucha -ancient neon monster portrait, intricate artwork by josan gonzalez, artgerm, h. r. giger, kilian eng, very coherent artwork, cinematic, hyper realism, vibrant, octane render, unreal engine, 8 k, high contrast, higly detailed black ink outline -twin peaks poster art, portrait of the black lodge has the blue colored rose trapped in a glass box, can david bowie find it, by michael whelan, rossetti bouguereau, artgerm, retro, nostalgic, old fashioned -the beautiful hyper detailed scene render that a beautiful girl lies in the arms of a huge silver dragon alone in the fairyland surrounded by white clouds, in the style of makoto shinkai victo ngai and peter mohrbacher studio ghibli artgerm karol bak beeple, animation style, 8 k hd, dream, ultra wide angle, animation style, 3 drender, hyperdetailed -portrait of a beautiful young fit male angel with curly blond hairs, dressed with fluent clothes, luminous scene, by Greg Rutkowski and alphonse mucha, d&d character, gradient white to cyan, in front of an iridescent background, highly detailed portrait, -a scene of a camper in the desert, a cowboy in the foreground looking epic, full shot, atmospheric lighting, detailed faces, by makoto shinkai, stanley artgerm lau, wlop, rossdraws -lalisa manoban of blackpink, knight armor, tarot card, highly detailed, digital painting, smooth, sharp focus, illustration, ultra realistic, 8 k, art by artgerm and alphonse mucha -feudal japan tokyo street at dusk, raining, detailed reflections, on a postcard, cinematic lighting!!, 4k, trending on artstation, detailed watercolour, rule of thirds, center focus, art by albert bierstadt -concept art by greg rutkowski, a gigantic spear - shaped starship approaches the system, huge and megalithic, plowing through space, frightening and creepy atmosphere, scifi, digital painting, artstation, concept art, smooth, sharp foccus ilustration, artstation hq -beautiful girl a strange wind blew in off the north sea, an eerie susurration that cut across the eastern sea, beautiful portrait, symmetrical, character concept style trending on artstation concept art detailed octane render cinematic photo - realistic 8 k high detailed -the street of a frozen village in ice that never the see the sun again, concept art by makoto shinkai and greg rutkowski, matte painting, trending on artstation -full length photo of a gorgeous young woman in the style of stefan kostic, realistic, sharp focus, 8k high definition, insanely detailed, intricate, elegant, art by stanley lau and artgerm -beautiful sci fi space scene with planets, concept art trending on artstation, volumetric lighting, 8k -brigitte from overwatch, character portrait, portrait, close up, concept art, intricate details, highly detailed, vintage sci - fi poster, retro future, vintage sci - fi art, in the style of chris foss, rodger dean, moebius, michael whelan, and gustave dore -will smith fights against demons dressed as a gladiator and with angel wings, cinematic lighting, highly detailed, concept art, art by wlop and artgerm and greg rutkowski, masterpiece, trending on artstation, 8 k -Till Lindemann crushing planet earth with his teeth. epic game portrait. Highly detailed, highly recommended. fantasy art by Greg Rutkowski -Art nouveau Ferarri, fantasy, intricate galactic designs, elegant, highly detailed, sharp focus, art by Artgerm and Greg Rutkowski and WLOP -walter white as lara croft, digital painting, extremely detailed, 4 k, intricate, brush strokes, mark arian, artgerm, bastien lecouffe - deharme -a swamp viewed from afar with one huge tree in the middle, dark colors, glowing plants, misty background, light rays, sunset!, birds, beautiful lighting, vivid colors, intricate, elegant, smooth, sharp focus, highly detailed digital painting, concept art, cinematic, unreal engine, 4 k wallpaper, svetlin velinov, tarmo juhola, artstation trending -wide angle, mage, sleeping on rock, white grey blue color palette, eyes closed, forest, female, d & d, fantasy, intricate, elegant, highly detailed, long brown hair, digital painting, artstation, octane render, concept art, matte, sharp focus, illustration, hearthstone, art by artgerm, alphonse mucha johannes voss -cinematic portrait of the incredible hulk, only head and chest, intricate, desaturated, Tim Hildebrandt, Wayne Barlowe, Bruce Pennington, donato giancola, larry elmore, maxfield parrish, Moebius, Thomas Ehretsmann, oil on canvas, gouache painting, masterpiece, trending on artstation, cinematic composition, dramatic pose, volumetric lighting, sharp, details, hyper-detailed, HD, 4K, 8K -cinematic bust portrait of futuristic robot from left, head and chest only, exotic alien features, robotic enhancements, desaturated, tim hildebrandt, wayne barlowe, bruce pennington, donato giancola, larry elmore, oil on canvas, masterpiece, trending on artstation, featured on pixiv, cinematic composition, dramatic pose, beautiful lighting, sharp, details, hyper - detailed, hd, hdr, 4 k, 8 k -perfectly detailed wisteria flowers!! blessed by nature with ever - increasing physical mental perfection, symmetrical! intricate, sensual features, highly detailed, biblical divine holy perfection!! digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -portrait of teenage girl with long glossy black hair, blue eyes, glowing skin, fashion model features, fantasy, intricate, elegant, black dress, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by Krenz Cushart and Artem Demura and alphonse mucha -a cinematic detailed painting of a black kid in the woods, volumetric light, surrealism, highly detailed, realistic, retro, in the style of francis bacon and james jean, trending on artstation, painting by Edward Hoper, colorful, realistic, smooth, octane render -concept art from zaha hadid, futuristic, ultra realistic, concept art, intricate details, highly detailed, photorealistic, octane render, 8 k -hyperrealistic mixed media painting of a grungy skull woman with rainbow hair, stitched together, soft eyes and narrow chin, dainty figure, long hair straight down, torn v plunge shirt, short shorts, combat boots, basic white background, side boob, wet tshirt, wet, raining, dim volumetric lighting, 8 k octane beautifully detailed render, post - processing, portrait, extremely hyper - detailed, intricate, epic composition, cinematic lighting, masterpiece, trending on artstation, very very detailed, masterpiece, stunning, -cat theme logo, cat theme banner, cat design, a smiling cat, art photography style, trending on artstation, warm light, lovely and cute, fantasy art, 8 k resolution -cover concept art of the lost sand city, levitating sand, ground view, golden towers, golden pillars, palm trees, space and time, floating objects, post-processing, in the style of Hugh Ferriss, Behance, Artgerm. High detail, ultra realistic render, octane, 3D, photorealism, symmetric, cinematic -male anime character, oni mask, organic, forest druid, dark souls boss, cyber punk, portrait, male anime character, robot, masterpiece, intricate, highly detailed, sharp, technological rings, by james mccarthy, by beeple and johfra bosschart, combination in the style ayami kojima, highly detailed, painting, 3 d render beeple, unreal engine render, intricate abstract, intricate artwork, by tooth wu, wlop, beeple, dan mumford. concept art, octane render, trending on artstation, greg rutkowski very coherent symmetrical artwork. cinematic, key art, hyper realism, high detail, octane render, 8 k, iridescent accents, albedo from overlord, the library of gems, intricate abstract. intricate artwork, by tooth wu, wlop, beeple, dan mumford. concept art, octane render, trending on artstation, greg rutkowski very coherent symmetrical artwork. cinematic, key art, hyper realism, high detail, octane render, 8 k, iridescent accents -Lionel Messi closeup, D&D style, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, art by Artgerm and Greg Rutkowski and Alphonse Mucha -young shadow mage male, joyful, d & d, fantasy, intricate, elegant, full body, highly detailed, digital painting, artstation, concept art, matte, sharp, illustration, hearthstone, art by artgerm and greg rutkowski and alphonse mucha -ultra realistic illustration, emma roberts from last of us, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -A beautiful cosmic entity || VERY ANIME, fine-face, realistic shaded perfect face, fine details. Anime. realistic shaded lighting poster by Ilya Kuvshinov katsuhiro otomo ghost-in-the-shell, magali villeneuve, artgerm, Jeremy Lipkin and Michael Garmash, Rob Rey and Kentar� Miura style, trending on art station -muscular gandhi at the beach, sitting on the sand next to a campfire, with palm trees in the back, by artgerm, ilya kuvshinov katsuhiro villeneuve, jeremy lipkin and michael garmash and rob rey, disney pixar zootopia, by tristan eaton, stanley artgermm, tom bagshaw, greg rutkowski, carne griffiths -A fancy portrait of an attractive humanoid creature by Greg Rutkowski, beeple, Sung Choi, Mitchell Mohrhauser, Maciej Kuciara, Johnson Ting, Maxim Verehin, Peter Konig, final fantasy, macro lens , 8k photorealistic, cinematic lighting, HD, high details, dramatic, dark atmosphere, trending on artstation -headless horseman in a marvel movie, science fiction industrial hard science concept art, 8K render octane high definition cgsociety, photorealistic, unreal engine 5 -a highly detailed metahuman 4 k close up render of a goddess bella hadid monument renaissance in iris van herpen dress schiaparelli in diamonds crystals swarovski and jewelry iridescent in style of alphonse mucha gustav klimt trending on artstation made in unreal engine 4 -closeup portrait shot of a ring wraith in a scenic dystopian environment, intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, wlop, boris vallejo -Redhead Pleiadian alien human beautiful hybrid feminine woman, long gorgeous red hair in loose curls, with stunning green eyes, cute round face and a roundish nose, as a retro futuristic heroine, gorgeous digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and donato giancola and Joseph Christian Leyendecker, Ross Tran, WLOP -gigachad luigi bodybuilder in a expensive dress suit by ilya kuvshinov, ernest khalimov body by krista sudmalis, fantasy character portrait, futuristic town background by laurie greasley, ultra realistic, concept art, intricate details, elegent, digital painting, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, artstation -painting of a gorgeous young woman in the style of Martine Johanna, draped in flowing fabric, colorful energetic brush strokes, realistic, sharp focus, 8k high definition, insanely detailed, intricate, elegant, art by Martine Johanna and artgerm -l � lawliet, hunchback, death note, d & d, fantasy, portrait, highly detailed, headshot, digital painting, trending on artstation, concept art, sharp focus, illustration, art by artgerm and greg rutkowski and magali villeneuve and wlop -a portrait of Chiefkeef in front of an Art Nouveau mandala wearing a huge elaborate detailed ornate crown made of all types of realistic colorful flowers, turban of flowers, sacred Geometry, Golden ratio, surrounded by scattered flowers peonies dahlias lotuses roses and tulips, photorealistic face, Cinematic lighting, rimlight, detailed digital painting, Portrait, headshot, in style of Alphonse Mucha, Artgerm, WLOP, Peter Mohrbacher, William adolphe Bouguereau, cgsociety, artstation, Rococo and baroque styles, symmetrical, hyper realistic, 8k image, 3D, supersharp, pearls and oyesters, turban of vibrant flowers, satin ribbons, pearls and chains, perfect symmetry, iridescent, High Definition, Octane render in Maya and Houdini, light, shadows, reflections, photorealistic, masterpiece, smooth gradients, no blur, sharp focus, photorealistic, insanely detailed and intricate, cinematic lighting, Octane render, epic scene, 8K -percy jackson in cyberpunk city, 4 k, trending on artstation. -wonderdream faeries lady feather wing digital art painting fantasy bloom vibrant style mullins craig and keane glen and apterus sabbas and guay rebecca and demizu posuka illustration character design concept colorful joy atmospheric lighting butterfly -Boris Johnson as Thor with hammer Mjolnir, Boris Johnson hairstyle, full body realistic portrait, highly detailed, muscular body, digital painting, artstation, concept art, smooth, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha -An ancient Iranian fortress as Far Cry 4 concept art, spring season, beautiful, gorgeous buildings, , concept art by Viktor Vasnetsov, concept art, ancient era, warm lighting, soft by Ivan Shishkin, Dimitri Desiron and Antonio Lopez Garcia, hyperborea, high resolution, trending on artstation, -high detailed white space station interior a statue jesus on cross made of red marble, perfect symmetrical body, full body shot, inflateble shapes, wires, tubes, veins, jellyfish, white biomechanical details, wearing epic bionic cyborg implants, masterpiece, intricate, biopunk, vogue, highly detailed, artstation, concept art, cyberpunk, octane render -Award-Winning. Trending on Artstation. 8K. Corrupted Knight infected with black obsidian glowing red. Angular. Sharp. Ready for battle. -2 0 year old ethiopian man, sitting on a black corvette, counting money, portrait, elegant, intricate, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by konstantin korovin and daniel f. gerhartz and john howe -beautiful ethereal cyberpunk jennifer lawrence, art nouveau, fantasy, intricate binary and electronic designs, elegant, highly detailed, sharp focus, art by artgerm and greg rutkowski and wlop -symmetry!! portrait of a horizon zero dawn machine acting as ironman, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, 8 k -beautiful portrait of a minority female wearing fantastic costume,pigtail,intricate, elegant, highly detailed, dim volumetric lighting, 8k,octane,post-processing,digital painting, trending on artstation, concept art, smooth, sharp focus, illustration,by Tom Bagshaw and Daniel Gerhartz and Albert Aublet and Lawrence Alma-Tadema and alphonse mucha -a female elf sorceress by karol bak and jia ruan, beautiful detailed eyes, cute, fantasy, intricate, elegant, highly detailed, digital painting, 4 k, hdr, concept art, detailed jewelry, smooth, sharp focus, illustration, art by artgerm -high quality 3 d render very cute cyborg labrador!! dog plays drums!, cyberpunk highly detailed, unreal engine cinematic smooth, in the style of blade runner & pixar, hannah yata charlie immer, moody light, low angle, uhd 8 k, sharp focus -concept art of an intelligent bear, bipedal, wearing glasses and a vest, holding a spellbook under his arm, anthromorphic, artstation, fantasy -symmetrical - face!! portrait shot of evil sithlord captain kirk from star trek in star wars, realistic, professionally, professionally color graded, intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, wlop, boris vallejo -glorious full head portrait of abraham lincoln as Batman, fantasy, intricate, elegant, digital painting, trending on artstation, concept art, sharp focus, illustration by Gaston Bussiere and artgerm, 4k. -a photorealistic 3 d seamless pattern of honey material with macro closeup details of circuits cables nvidia motherboard pcb futuristic robotic elements in glass and mirror in the style of zaha hadid, 3 d realistic model render in cyberpunk 2 0 7 7 colors, unreal engine 5, keyshot, octane, artstation trending, ultra high detail, ultra realistic, cinematic, 8 k, 1 6 k, large realistic elements in style of nanospace michael menzelincev, in style of lee souder, in plastic, dark atmosphere, tilt shift, depth of field -skull - headed robot cyborg painting, illutstration, concept art, cyberpunk, futurism, comics art, artgerm -hyper realistic portrait, beautifully rendered, luis guzman as luigi wearing green, smirking deviously, painted by greg rutkowski, wlop, artgerm, dishonored 2 -mahindra thar driving through madagascar with baobabs trees, artgerm and greg rutkowski and alphonse mucha, an epic fantasy, volumetric light, detailed, establishing shot, an epic fantasy, trending on art station, octane render, midsommar -kurdish! assassins creed game set in kurdistan!, concept art, digital painting, highly detailed, 8 k, high definition -portrait of ((mischievous)), baleful young Cate Blanchett as young Galadriel as a queen of fairies, dressed in a beautiful silver dress. The background is a dark, creepy eastern europen forrest. night, horroristic shadows, high contrasts, lumnious, photorealistic, dreamlike, (mist filters), theatrical, character concept art by ruan jia, thomas kinkade, and J.Dickenson, trending on Artstation -elephant yoda playin socker, stunning digital art, high detail, in the style of artgerm, artstation, cgsociety, dramatic lighting, pixar 3d 8k -photo of nikolas cage as ken from street fighter 2, shoulder length hair, high - contrast, intricate, action pose, highly detailed, centered, digital painting, artstation, smooth, sharp focus, illustration, artgerm, tomasz alen kopera, peter mohrbacher, donato giancola, joseph christian leyendecker, wlop, boris vallejo -a portrait of frodo baggins, fantasy, sharp focus, intricate, elegant, digital painting, artstation, matte, highly detailed, concept art, illustration, ambient lighting, art by ilya kuvshinov, artgerm, alphonse mucha, and greg rutkowski -a very beautiful anime elf girl, full body, long silver hair with a flower, sky blue eyes, full round face, short smile, revealing clothes, thick thigs, firm chest, ice snowy lake setting, cinematic lightning, medium shot, mid-shot, highly detailed, trending on Artstation, Unreal Engine 4k, cinematic wallpaper by Stanley Artgerm Lau, WLOP, Rossdraws, James Jean, Andrei Riabovitchev, Marc Simonetti, and Sakimichan -a League of Legends FAN ART Portrait of VI, pink hair, short hair, elegant, highly detailed, digital painting, concept art, smooth, sharp focus, illustration, by Laurie Greasley,Lawrence Alma-Tadema,Dan Mumford,artstation,deviantart,Unreal Engine,face enhance,8K,golden ratio,cinematic lighting -!dream concept art, four glam rockers dressd as a mix of hooligans and whores, walking down a dark wet london alley at night, by ashley wood, by roger deakins, atmospheric -art portrait of death, 8 k, by tristan eaton, stanley artgermm, tom bagshaw, greg rutkowski, carne griffiths, trending on deviantart, face enhance, hyper detailed, minimalist cinematic lighting, trending on artstation, 4 k, hyperrealistic, focused, extreme details, unreal engine 5, cinematic, masterpiece, full of colour, -A beautiful robotic woman dreaming, cinematic lighting, soft bokeh, sci-fi, modern, colourful, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, by greg rutkowski -highly detailed vfx portrait of ichigo kurosaki from bleach by tite kubo!!!, stephen bliss, greg rutkowski, loish, rhads, beeple, makoto shinkai, tom bagshaw, alphonse mucha, sharp focus, art by artgerm and greg rutkowski, stanley kubrick, backlit!!, -fantasy city at night while giant ball of fire crashes to the ground, surreal, digital art, concept art, highly detailed, trending on artstation -concept art of a lightray trapped in vacuum, high definition, symmetrical, insanely detailed, elegant, intricate, hypermaximalist, cgsociety, prizewinning, trending on artstation, popular, top 1 0 0, best, winner, mentor, guru -a dream microphone in a dystopic world full of aberration, black & white, melting, webbing, 8 k, by tristan eaton, stanley artgerm, tom bagshaw, greg rutkowski, carne griffiths, ayami kojima, beksinski, giger, trending on deviantart, face enhance, hyper detailed, minimalist, horror, alien -link from zelda using computer, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, 8 k -lofi steampunk portrait pixar style by (((Lita Cabellut))) and Stanley Artgerm and Tom Bagshaw -fractional reserve banking, watercolor, trending on artstation -a painting of a tank getting shot at in world war 2 by Bernardo Bellotto, high detail, hyperrealistic, concept art, artstation, 8k -a beautiful diva sings on the theater stage , octane render, cgsociety, artstation trending, palatial scene, highly detailded -Ghibli, good day, landscape, no people, no man, fantasy, wood, vibrant world, Anime Background, concept art, illustration,smooth, sharp focus, intricate, super wide angle, trending on artstation, trending on deviantart, Hayao Miyazaki, 4K -sapphire viking warrior, regal, elegant, winter, snow, beautiful, stunning, hd, illustration, epic, d & d, fantasy, intricate, elegant, highly detailed, wide angle, digital painting, artstation, concept art, smooth, sharp focus, illustration, wallpaper, art by artgerm and greg rutkowski and alphonse mucha and jin xiaodi -fullbody!! dynamic action pose, beautiful woman with blue hair, antlers on her head, long flowing intricate black dress, dnd, face, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -A masterpiece ultrarealistic ultradetailed portrait of a Incredibly beautiful llama with dreadlocks IN INCREDIBLE GLASSES. baroque renaissance. in the forest. White corset. medium shot, intricate, elegant, highly detailed. trending on artstation, digital art, by Stanley Artgerm Lau, WLOP, Rossdraws, James Jean, Andrei Riabovitchev, Marc Simonetti, Yoshitaka Amano. background by James Jean and Gustav Klimt, light by Julie Bell, 4k, porcelain skin. BY ZDIZISLAW BEKSINSKI Cinematic concept art -young harry potter as a gepard with gepard skin patterns hyper detailed, digital art, trending on artstation, cinematic lighting -a dik dik monster with tattoos, wearing a fedora, tattoos, colorful, digital art, fantasy, magic, trending on artstation, ultra detailed, professional illustration by basil gogos -a astronaut walking on a alien planet with alien plants and looking to a alien breathtaking landscape, cinematic lighting, concept art, trending on Artstation, trending on DeviantArt, highly detailed, high quality, 8K HDR, octane render, unreal engine 5, breathtaking landscape, highly detailed, high quality, post processed -skeleton geisha in a burdel, Tending on artstation, concept art, dark colors, 8k -realistic attractive grungy woman with rainbow hair, drunk, angry, soft eyes and narrow chin, dainty figure, long hair straight down, torn overalls, basic white background, side boob, tattooed, pierced, flirty, wet shirt, wet, raining, highly detailed face, realistic face, beautiful detailed eyes, fantasy art, in the style of greg rutkowski, illustration, epic, fantasy, intricate, hyper detailed, artstation, concept art, smooth, sharp focus, ray tracing, vibrant, -colossal orange viking royal king tabby cat, golden hour, fantasy, vivid colors, sharp focus, digital art, hyper - realistic, 4 k, unreal engine, highly detailed, hd, dramatic lighting by brom, trending on artstation -pencial drawing concept art of a machine mutant martial artist in the style of akira toriyama / hirohiko araki / tite kubo / masashi kishimoto trending on artstation deviantart pinterest detailed realistic hd 8 k high resolution -goth rainbow bright, fantasy, d & d, intricate, detailed, by by alphonse mucha, adolfo hohenstein, alice russell glenny, stanley artgerm lau, greg rutkowski, detailed, trending on artstation, trending on artstation, smooth -symmetry!! the eternal struggle of good and evil, very detailed, perfect lighting, perfect composition, 4 k, artstation, artgerm, derek zabrocki, greg rutkowski -portrait of beautiful cute young goth girl with glasses, cyberpunk, high details, neon, art by ( ( ( kuvshinov ilya ) ) ) and wayne barlowe and gustav klimt and artgerm and wlop and william - adolphe bouguereau -young Erin Gray as a ruggedly beautiful retro SCI-FI space heroine 1985 , intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and donato giancola and Joseph Christian Leyendecker, Ross Tran, WLOP -a large colorful candy cane is sticking out the ground on the side of a serene foot path. there are some snow drifts laying against the candy. there are snow flurries in the air. epic, awe inspiring, dramatic lighting, cinematic, extremely high detail, photorealistic, cinematic lighting, trending on artstation cgsociety rendered in unreal engine, 4 k, hq, -a hyper - detailed 3 d render like a oil painting of the construction of a upward spiral, surrealism!!!!! surreal concept art, lifelike, photorealistic, digital painting, aesthetic, smooth, sharp focus, artstation hd, by greg rutkowski, bruce pennington, valentina remenar and asher duran, -a octane render of a violent tornado inside a jar, close - up studio photo, studio lighting, path traced, highly detailed, high quality, hyperrealistic, concept art, digital art, trending on artstation, cinematic, high coherence, epic scene, 8 k hdr, high contrast -portrait of a young, ruggedly handsome ranger, muscular, half body, leather, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -the avengers fighting thanos, long shadow, warm colors, by Greg Rutkowski, artstation -a person looking like vladimir putin riding giant steel krab, masterpiece, intricate, elegant futuristic wardrobe, highly detailed, digital painting, artstation, concept art, crepuscular rays, smooth, sharp focus, illustration, background galaxy, cyberpunk colors, volumetric lighting, art by artgerm and james jean and nick sullo -book cover!!!!!!!!!!!!, old bridge, ivy vector elements at each border, fantasy forest landscape, fantasy magic, light night, intricate, elegant, sharp focus, illustration, highly detailed, digital painting, concept art, matte, art by wlop and artgerm and ivan shishkin and andrey shishkin, masterpiece -a modernist courtroom in the rainforest by raphael, hopper, and rene magritte. detailed, proportional, romantic, vibrant, enchanting, achingly beautiful, graphic print, trending on artstation, jungle, tropical, foliage, flowering, blooming -portrait of a beautiful mysterious woman holding a bouquet of flowing flowers, hair flowing upwards, small bubbles from her mouth, hands hidden under the bouquet, submerged underwater filled with colorful small fish and coral reef, fantasy, regal, intricate, by stanley artgerm lau, greg rutkowski, thomas kindkade, alphonse mucha, loish, norman rockwell -portrait of a friendly charming formal barbarian giant noble!, imperial royal elegant clothing, elegant, rule of thirds, extremely detailed, artstation, concept art, matte, sharp focus, art by greg rutkowski, cover by artgerm -goldfinger, character sheet, concept design, contrast, kim jung gi, greg rutkowski, zabrocki, karlkka, jayison devadas, trending on artstation, 8 k, ultra wide angle, pincushion lens effect -a watercolor ink painting of scooby - doo as the primordial eldritch god of natural - disasters in the style of jean giraud in the style of moebius trending on artstation deviantart pinterest detailed realistic hd 8 k high resolution -zidane and shrek wearing vr playing gta v, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, art by greg rutkowski and alphonse mucha -full body portrait of marvel cinematic universe aaliyah haughton, she venom, spider man, elegant, webs, super hero, spider web background, highly detailed!! digital painting, artstation, glamor pose, concept art, sharp focus, illustration, art by artgerm and greg rutkowski, artey freytag -demonic evil cute fourteen year old brown skinned asian girl, tomboy, evil smile, freckles!!!, fully clothed, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, cinematic lighting, art by artgerm and greg rutkowski and alphonse mucha, -renfri, the princess turned gang leader from the witcher universe. fantasy art by greg rutkowski, gustave courbet, rosa bonheur, edward hopper. faithfully depicted facial expression, perfect anatomy, sharp focus, global illumination, radiant light, detailed and intricate environment, trending on artstation -A chef with a big mustache proundly making a soup, digital painting, artstation, concept art, Craig Mullins, Breathtaking, 8k resolution, extremely detailed, beautiful, establishing shot, artistic, hyperrealistic, octane render, cinematic lighting, dramatic lighting, masterpiece, light brazen, extremely detailed and beautiful face -a space realistic robot with big and cute eyes, | | very anime, fine - face, realistic shaded robotic parts, fine details. anime. realistic shaded lighting poster by ilya kuvshinov katsuhiro otomo ghost - in - the - shell, magali villeneuve, artgerm, jeremy lipkin and michael garmash, rob rey and kentaro miura style, trending on art station -Portrait of The Most Beautiful old Woman On Earth , D&D, fantasy, intricate, richly detailed colored 3D illustration of a beautiful ornated cute body with long metallic hair wearing a hoodie and short skirt that is happy and curious smile. background with completely rendered reflections, art by Range Murata and Artgerm highly detailed, digital painting, trending on artstation, sharp focus, illustration, style of Stanley Artgerm, perfect smile and sexy mouth, -lucifer cast out of heaven by yusuke murata and makoto shinkai, clouds, fire, angels, 8k, cel shaded, unreal engine, featured on artstation, pixiv -A pirate ship in the middle of the sea during a storm, fantasy art, in the style of greg rutkowski, illustration, epic, fantasy, intricate, hyper detailed, artstation, concept art, smooth, sharp focus, ray tracing -fox as a monkey, fluffy white fur, black ears, stunning green eyes, extremely long white tail with black tip, award winning creature portrait photography, extremely detailed, artstation, 8 k, sensual lighting, incredible art, wlop, artgerm -autumn in french village, ornate, beautiful, atmosphere, vibe, mist, smoke, fire, chimney, rain, wet, pristine, puddles, melting, dripping, snow, creek, lush, ice, bridge, green, stained glass, forest, roses, flowers, by stanley artgerm lau, greg rutkowski, thomas kindkade, alphonse mucha, loish, norman rockwell -Keanu Reeves as spiderman , film still, muscle extremely detailed, fantastic details full face, mouth, trending on artstation, pixiv, cgsociety, hyperdetailed Unreal Engine 4k 8k ultra HD, WLOP -symmetry!! portrait of elon musk with a salvador dali moustache intricate, neon lights, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski -Movie still of danny devito as as Harry Potter in potions class at hogwarts, fantasy, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, art by artgerm and Tony Sart -a planet that resembles a skull, stars in the background, natural, ultra detail. digital painting, beautiful, concept art, ethereal, cinematic, epic, 8k, highly detail, insane detailed, oil painting, octane render, cinematic lighting, smooth, sharp, Artstation, mystical, illustration, Trending on Artstation, Artstation HQ, Artstation HD, digital art, -anthropomorphic art of a businessman dragon, green dragon, dragon head, portrait, victorian inspired clothing by artgerm, victo ngai, ryohei hase, artstation. fractal papers and books. highly detailed digital painting, smooth, global illumination, fantasy art by greg rutkowsky, karl spitzweg -Billie Eilish, sitting in a cafe, fantasy, intricate, elegant, highly detailed, digital painting, pale skin, artstation, concept art, matte, sharp focus, illustration, art by Artgerm and Greg Rutkowski and Alphonse Mucha -a tornado made of fire on a field, au naturel, hyper detailed, digital art, trending in artstation, cinematic lighting, studio quality, smooth render, unreal engine 5 rendered, octane rendered, art style by klimt and nixeu and ian sprigger and wlop and krenz cushart -a queue of grey people looking like perfect copies of each other, in the style of artgerm, gerald brom, atey ghailan and mike mignola, vibrant colors and hard shadows and strong rim light, plain background, comic cover art, trending on artstation -vampire in the style of stefan kostic, realistic, full body shot, wide angle, sharp focus, 8 k high definition, insanely detailed, intricate, elegant, art by stanley lau and artgerm, floating embers -fluffy cat in cowboy hat like a tiny girl riding on the back of a giant corgi, by greg rutkowski -beautiful black woman elf wearing a dark green robe portrait, art nouveau, fantasy, intricate arcane wiccan designs, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, art by Artgerm and Greg Rutkowski and WLOP -portrait of a wizard, intricate, highly detailed, digital painting, artstation, concept art, sharp focus, art by huifeng huang and greg rutkowski -daredevil portrait, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and alphonse mucha -a highly detailed illustration of tall beautiful red haired lady wearing black spaghetti strap noir style dress and sun hat, elegant stroking face pose, intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, league of legends concept art, wlop. -a hooded wise old man with a long white beard wearing a brown hooded tunic riding on top of a lion, the man riding is on the lion, the wise man is riding on top, he is all alone, majestic, epic digital art, cinematic, trending on artstation, superb detail 8 k, wide angle shot, masterpiece -a lisa frank mcdonalds microwaved happymeal, gothic, highly detailed, digital painting, artstation, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha and william - adolphe bouguereau -a beautiful highly detailed matte painting of a building looking like a goose by Jose Daniel Cabrera Pena and Leonid Kozienko, concept art by Tooth Wu and wlop and beeple and dan mumford and greg rutkowski and nekroxiii. octane render, cinematic, hyper realism, octane render, 8k, iridescent accents. vibrant, teal and gold blue red dark noir colour scheme -a statue made of red marble, of an beautiful girl, full body shot, perfect body, red white biomechanical, inflateble shapes, wearing epic bionic cyborg implants, masterpiece, intricate, biopunk futuristic wardrobe, vogue, highly detailed, artstation, concept art, background galaxy, cyberpunk, octane render -a ultradetailed beautiful panting of scarlett johansson as motoko kusanagi, by conrad roset, greg rutkowski and makoto shinkai, trending on artstation -a detailed portrait of a weasel assassin dressed with a leather armor, by justin gerard and greg rutkowski, digital art, realistic painting, dnd, character design, trending on artstation -a soldier zombie with a gas mask, pile of skulls, horror, black and white, fantasy art, monster art, illustration, fantasy, intricate, hyper detailed, artstation, concept art, smooth, sharp focus, ray tracing -yvonne strahovski, very sexy penguin outfit, medium shot, visible face, detailed face, perfectly shaded, atmospheric lighting, by makoto shinkai, stanley artgerm lau, wlop, rossdraws -concept art of love, death + robots series of netflix, cinematic shot, oil painting by jama jurabaev, brush hard, artstation, for aaa game, high quality, brush stroke -Ottoman Emperor George Washington, diffuse lighting, fantasy, intricate, elegant, highly detailed, lifelike, photorealistic, digital painting, Ottoman armor, artstation, illustration, concept art, smooth, sharp focus, art by John Collier and Albert Aublet and Krenz Cushart and Artem Demura and Alphonse Mucha -Full potrait of cinead o'connor as an angel, hyper realistic, prismatic highlights, atmosphere, gorgeous, depth of field, cinematic, macro, concept art, 50mm, artstation, wlop, elegant, epic, weta digital, focus, octane render, v-ray, 8k, kodak portra, art by Liberatore -a film still of of a woman explorer, ( emerald herald ), exploring lost ruins, sun lighting, water, finely detailed features, perfect art, at an ancient city, gapmoe yandere grimdark, trending on pixiv fanbox, painted by greg rutkowski makoto shinkai takashi takeuchi studio ghibli,, akihiko yoshida -a very beautiful young yuuki asuna, full body, long wavy blond hair, sky blue eyes, full round face,, bikini, miniskirt, front view, mid - shot, highly detailed, cinematic wallpaper by stanley artgerm lau -symmetry!! portrait of jair bolsonaro, sci - fi, tech wear, glowing lights!! intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -an art and technology t - shirt, digital art from artstation, by ruan jia and mandy jurgens and artgerm and william - adolphe bouguereau fantasy, epic digital art, volumetrc lighting, clean detail 8 k resolution -gamora, portrait, digital painting, elegant, beautiful, highly detailed, artstation, concept art -a mechanized version of a norse woman, facial piercings, very symmetrical, furry warrior's bone clothing, highly detailed, by vitaly bulgarov, joss nizzi, ben procter, steve jung, concept art, concept art world, pinterest, artstation, unreal engine -photorealistic dwayne johnson but he is made of rocks. hyperdetailed photorealism, 1 0 8 megapixels, amazing depth, glowing rich colors, powerful imagery, 3 d finalrender, 3 d shading, cinematic lighting, artstation concept art -anime young boy with short wavy white hair wearing white clothes with short cape surrounded by light orbs, moody, wlop, concept art, digital painting, trending on artstation, highly detailed, epic composition, 8 k uhd -a photo of 8 k ultra realistic humanoid princess standing next to a beautiful view, ornate white and gold officers outfit, cinematic lighting, trending on artstation, 4 k, hyperrealistic, focused, extreme details, unreal engine 5, cinematic, masterpiece -epic 3 d abstract model, liquid headdress, 2 0 mm, with pastel pink and cerulean peanut butter, melting smoothly into other faces, liquid, delicate, beautiful, intricate, houdini sidefx, trending on artstation, by jeremy mann and ilya kuvshinov, jamie hewlett and ayami kojima -Idris Elba as Superman (2019), zac snyder, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -kneeling before a condescending queen, royal gown, golden detailing, medium shot, intricate, elegant, highly detailed, digital painting, volumetric light, artstation, concept art, smooth, sharp focus, illustration, art by Gil Elvgren and Greg Rutkowski and Alphonse Mucha, 8K -a highly detailed and high technology alien spacecraft, centered, corals, plume made of geometry, water texture, wet, wet lighting, extremly detailed digital painting, sharp focus in the style of android jones, artwork of a futuristic artificial intelligence superstar with frames made of detailed circuits, mystical colors, rim light, beautiful lighting, 8 k, stunning scene, raytracing, octane, under water visual distortion, dark tones colors, trending on artstation -metalhead, by yoshitaka amano, ruan jia, kentaro miura, artgerm, detailed, intricate details, trending on artstation, hd, masterpiece -futuristic utopian city, central hub, white buildings, golden sunset, space ships, green trees, large flying drones, utopia, high quality, hopeful, beautiful design, scifi, high detail, global illumination, trending on artstation, art by richard dumont, leon tukker -Fae teenage girl, portrait, face, long red hair, green highlights, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -charizard flying above new york, highly detailed matte fantasy painting, stormy lighting, by ross tran, by artgerm, by lisa frank, by brom, by peter mohrbacher -Glowing glass jar with a pink tentacle in green liquid, macro, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, volumetric lighting, cinematic, illustration, art by Artgerm and Greg Rutkowski and Alphonse Mucha -jazz music, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by wlop, mars ravelo and greg rutkowski -concept art of fried egg, highly detailed painting by dustin nguyen, akihiko yoshida, greg tocchini, greg rutkowski, cliff chiang, 4 k resolution, trending on artstation, 8 k -portrait of a rugged ranger, muscular, upper body, hairy torso, detailed detailed detailed hands hands hands hands, D&D, fantasy, bare bare bare bare thighs thighs thighs intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm -an extremely psychedelic portrait of hunter s. thompson, surreal, lsd, face, detailed, intricate, elegant, lithe, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration -greg manchess portrait painting of snufkin as overwatch character, medium shot, asymmetrical, profile picture, organic painting, nebula, matte painting, bold shapes, hard edges, street art, trending on artstation, by huang guangjian and gil elvgren and sachin teng -portrait of abandoned ribbed sculpture of two kissing cyborgs, covered with tentacles, roots, wires, tubes, ash, mold, baroque painting, standing in a desolate empty wasteland, creepy, nightmare, dream-like heavy atmosphere, dark fog, surreal abandoned buildings, baroque painting, beautiful detailed intricate insanely detailed octane render trending on Artstation, 8K artistic photography, photorealistic, volumetric cinematic light, chiaroscuro, zoomed out, Raphael, Caravaggio, Beksinski, Giger -underwater naga portrait, Pixar style, by Tristan Eaton Stanley Artgerm and Tom Bagshaw. -priestess with angelical wings, golden hair, fluorescent eyes, white skin, lipstick, beautiful, goodness, high fantasy, illustration, by artgerm, greg rutkowski, alphonse mucha -a warlock is casting a magic spell, with magic orb floating in his hand , dynamic pose, natural lighting, medium level shot, Mucha style , Grim fantasy, illustration ,concept art, -portrait of the secretive vampire woman biker loner smiling at her cat, by yoshitaka amano, casey baugh, steve caldwell, gottfried helnwein, yasunari ikenaga, nico tanigawa, and artgerm rendered with 3 d effect. -aliens in Jerusalem, concept art, hd -many Alchemy Imperial legends knights super hero boys girl, sci-fi, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, fractal flame, amazing composition unreal engine -concept art, of buffaloes on a beach, sunset, 30mm, canon, very hot, crowded, artstation -portrait of john candy crying, john candy suffering, metaverse on fire, octane render, trending on artstation -a portrait of a cyborg josip broz tito. vaporwave, intricate, epic lighting, cinematic composition, hyper realistic, 8 k resolution, unreal engine 5, by artgerm, tooth wu, dan mumford, beeple, wlop, rossdraws, james jean, marc simonetti, artstation -anime portrait of the priestess in the forest, enchanted, magic, digital, concept art, Kyoto animation,last exile, blue submarine no. 6, katsura masakazu,tsutomu nihei, gustav klimt,loish, murata range, kawaii, studio lighting, manga, bright colors, anime,beautiful, 35mm lens,noir, vibrant high contrast, gradation, jean giraud, moebius, fantasy, rule of thirds, unreal engine, fibonacci, intricate, cel shaded, blender npr, flat, matte print, smooth, Ilya Kuvshinov, Tsuruta Kenji -a large 1 8 th century pirate airship flying among the clouds, soaring through the sky, airship, digital art, pirate ship, vivid colors, artgerm, james gilleard, beautiful, highly detailed, intricate, trending on art station -Taylor Swift Cosplaying Lola Bunny, modeling, posing, two piece workout clothes, training bra, quality lighting, vibrant colors, maximalism, facial details, photograph of Taylor Swift, Tooth Wu Artgerm WLOP artstation deviantart, 8k, fanart, playboy style, very very aesthetic -a cartoon pineapple holding a large glass of port, nightclub, elegant, real life skin, intricate, high detailed, artstation, concept art, smooth, sharp focus, art by artgerm and greg rutkowski -powerful goddess of water clothed in swirling water striding through a stormy sea, dress made of water, highly detailed matte fantasy painting, rendered in octane, stormy lighting, by ross tran, by artgerm, by david suh, by peter mohrbacher -an extremely detailed matte painting emma watson as borg nine star trek, digital painting, beautiful eyes!, pretty face!!, symmetry, concept art, sharp focus, illustration, art by artgerm! greg rutkowski magali villeneuve wlop! ilya kuvshinov!!, octane render -bruce campbell as harry potter in “ harry potter and the philosopher's stone ” ( 2 0 0 1 ). movie still detailed, smooth, sharp focus. -a beautiful portrait of a tree goddess by Greg Rutkowski and Raymond Swanland, Trending on Artstation, ultra realistic digital art -a beautiful masterpiece painting of the last poet whispering,'if all can begin again, then everything must continue!'by juan gimenez, long shiny black hair blue eyes, award winning, trending on artstation, photorealistic, hyperrealism, octane render, unreal engine -cabin high on a mountain, the valley beneath, dynamic lighting, photorealistic fantasy concept art, trending on art station, stunning visuals, creative, cinematic, ultra detailed -a painting so beautiful and universally loved it creates peace on earth, profound epiphany, trending on artstation, by john singer sargent -Majestic powerfull red white Winged Hussars cavalry horde charging at ugly rainbow demons and trolls on ground, huge golden cross above them on the sky, white red eagle helping hussars, blood, snow, wide angle, professional kodak lenses, magic, fire, face painting, dramatic lighting, intricate, wild, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha, footage from space camera -bob ross!! riding a dinosaur, giant paintbrush in hand, model pose, ultra realistic, concept art, intricate details, eerie, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and alphonse mucha -Concept art of a Toilet-Plunger designed by Apple Inc -colorful medieval botanical garden, ornate, beautiful, atmosphere, vibe, mist, smoke, chimney, rain, well, wet, pristine, puddles, waterfall, melting, dripping, snow, ducks, creek, lush, ice, bridge, cart, forest, flowers, concept art illustration, color page, 4 k, tone mapping, akihiko yoshida, james jean, andrei riabovitchev, marc simonetti, yoshitaka amano, digital illustration, greg rutowski, volumetric lighting, sunbeams, particles, trending on artstation -a synthwave cuber bokeh brain, tristan eaton, victo ngai, artgerm, rhads, ross draws -portrait of korean beautiful female necromancer, face, dark fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -Intergalactic plant store floating in space with white twinkling stars in the foreground, galactic terrarium filled with plants from alien planets floating in the cosmos, Filled with plants, warm ethereal glowing ambiance, concept art 8k resolution -portrait of a friendly charming formal barbarian giant noble!, imperial royal elegant clothing, elegant, rule of thirds, extremely detailed, artstation, concept art, matte, sharp focus, art by greg rutkowski, cover by artgerm -artgerm, joshua middleton comic cover art, full body pretty even rachel wood faye, symmetrical eyes, symmetrical face, long curly black hair, beautiful forest, cinematic lighting -a forgotten garden gnome in a vast barren desert, hopeless wasteland background with a relentless raging sun overhead, an ultrafine detailed painting by stanley artgerm lau, greg rutkowski, thomas kindkade, alphonse mucha, loish, trending on deviantart, pop surrealism, whimsical, lowbrow, perfect symmetrical face, grotesque -Portrait of a tall beautiful brown-skin elf woman wearing stylish black and gold robes, warm smile, intricate, elegant, highly detailed, digital painting, smooth, sharp focus, artstation, graphic novel, art by stanley artgerm and greg rutkowski and peter mohrbacher, -a giant broken robots in rain after a huge battle, tired, rustic, dormant, sharp focus, james gilleard, cinematic, game art, extremely detailed digital painting, print -biolevel 4 secret lab, alien autopsy, wide angle, super highly detailed, professional digital painting, artstation, concept art, smooth, sharp focus, no blur, no dof, extreme illustration, unreal engine 5, photorealism, hd quality, 8 k resolution, cinema 4 d, 3 d, beautiful, cinematic, art by artgerm and greg rutkowski and alphonse mucha and loish and wlop -Gertrude Abercrombie, minimalistic graffiti masterpiece, minimalism, 3d abstract render overlayed, black background, psychedelic therapy, trending on ArtStation, ink splatters, pen lines, incredible detail, creative, positive energy, happy, unique, negative space, face, artgerm -a dramatic, epic, ethereal painting of a !!handsome!! thicc chunky beefy mischievous shirtless man with a big beer belly wearing a large belt and cowboy hat offering a whiskey bottle | he is relaxing by a campfire | background is a late night with food and jugs of whisky | homoerotic | stars, tarot card, art deco, art nouveau, intricate | by Mark Maggiori (((and Alphonse Mucha))) | trending on artstation -: sphere sculpture covered with maze pattern,hyper detailed art station parabolic lighting contest winners unrealengine trending on artstation,cinematic, hyper realism, high detail, octane render, 8k -starfinder lashunta pilot, wearing a flight suit, in a space port, intricate, elegant, highly detailed, digital painting, artstation, concept art, matte, sharp focus, illustration, art by artgerm and greg rutkowski -concept art of a futuristic gold warrior, large gold apendages on it's back, with a black obsidian helmet, tight armor, rough and jagged design | | epic - fine - fine details by stanley artgerm lau, wlop, rossdraws, and sakimichan, trending on artstation, brush strokes -a study of cell shaded cartoon of a monk on a skateboard with technical analysis charts in the background, illustration, wide shot, subtle colors, post grunge, concept art by josan gonzales and wlop, by james jean, Victo ngai, David Rubín, Mike Mignola, Laurie Greasley, highly detailed, sharp focus, alien, Trending on Artstation, HQ, deviantart, art by artgem -potato house interior design, Greg Rutkowski, trending on Artstation, 8K, ultra wide angle, pincushion lens effect. -a angry knight in full plate of black armor, splattered with blood, riding a large black war horse, with red glowing eyes flowing red mane and tail, blackened clouds cover sky, crackling with lightning, a castle in distance burns, concept art by greg rutkowski, craig mullins, todd mcfarlane, -sexy painting of 3 5 0 - pound taylor swift, red bikini, navel piercing, ultra realistic, sharp details, subsurface scattering, intricate details, warm lighting, beautiful features, highly detailed, photorealistic, octane render, 8 k, unreal engine, art by artgerm and greg rutkowski and alphonse mucha -the grand canyon filled with glowing futuristic cyberpunk skyscrapers at night with a starry sky, cinematic, wide angle establishing shot, fantasy, hyperrealism, greg rutkowski, tuomas korpi, volumetric light, octane render, photorealistic concept art, highly detailed, very intricate -Dwight Shrute as blue man. digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and donato giancola and Joseph Christian Leyendecker, Ross Tran, WLOP -death, dark fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, wallpaper, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -a realistic illustration portrait of a beautiful cute girl with wavy black red hair, a pointy nose and, round chin black eyeliner, green pupills, trending on artstation, hyper - realistic lighting, intricate by imagineartforyou -looking out to see a long wood dock on the water, child at end of dock, big fishing boat leaving the dock with sailors waving, low angle, long lens, sunset, a mediterranean phoenician fishing village in the distance, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, art by artgerm and greg rutkowski and raphael lacoste and magali villeneuve -splash art for new champion for league of legend, by riot games. trending on artstation -Anime as Elizabeth Olsen playing Scarlet Witch || cute-fine-face, pretty face, realistic shaded Perfect face, fine details. Anime. realistic shaded lighting poster by Ilya Kuvshinov katsuhiro otomo ghost-in-the-shell, magali villeneuve, artgerm, Jeremy Lipkin and Michael Garmash and Rob Rey as Scarlet Witch in New York cute smile -a portrait of apocalypse from x - men, fantasy, sharp focus, intricate, elegant, digital painting, artstation, matte, highly detailed, concept art, illustration, ambient lighting, art by ilya kuvshinov, artgerm, alphonse mucha, and greg rutkowski -portrait of radical lolita girl, dreamy and ethereal and dark, dark eyes, smiling expression, ornate goth dress, dark fantasy, chaotic, elegant, black crows flying, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -photography of man playing realistic virtual reality game in a giant mine with excavators and gnomes 3 d realistic model render in the style of zaha hadid with point cloud in the middle, in cyberpunk 2 0 7 7 colors, unreal engine 5, keyshot, octane, artstation trending, ultra high detail, ultra realistic, cinematic, 8 k, 1 6 k, in style of zaha hadid, in style of nanospace michael menzelincev, in style of lee souder, in plastic, dark atmosphere, tilt shift, depth of field -greg manchess portrait painting of armored starlord as overwatch character, medium shot, asymmetrical, profile picture, organic painting, sunny day, matte painting, bold shapes, hard edges, street art, trending on artstation, by huang guangjian and gil elvgren and sachin teng -full lenght shot, super hero pose, biomechanical dress, inflateble shapes, wearing epic bionic cyborg implants, masterpiece, intricate, biopunk futuristic wardrobe, highly detailed, art by akira, mike mignola, artstation, concept art, background galaxy, cyberpunk, octane render -alterd carbon, masked angel protecting girl and a woman, vampre the masquerade, neon, detailed intricate render, dark atmosphere, detailed illustration, hd, 4 k, digital art, overdetailed art, surrealistic, by greg rutkowski, by loish, complementing colors, trending on artstation, deviantart -fullbody portrait of a beautiful girl dressed in cyberpunk style, standing on street, holding a sniper rifle. by riot games, anime style, masterpiece, award - winning, trending on artstation and pixiv -thief red riding hood, d & d, fantasy, portrait, highly detailed, digital painting, trending on artstation, concept art, sharp focus, illustration, art by artgerm and greg rutkowski and magali villeneuve -anthropomorphic highly detailed group portrait of funny neon giant cute eyes dust mephit, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm, bob eggleton, michael whelan, stephen hickman, richard corben, wayne barlowe, trending on artstation and greg rutkowski and alphonse mucha, 8 k -beautiful girl galaxy background, portrait character concept style trending on artstation concept art detailed octane render cinematic photo - realistic 8 k high detailed -realistic render of flying blue whales towards the moon, intricate, toy, sci - fi, extremely detailed, digital painting, sculpted in zbrush, artstation, concept art, smooth, sharp focus, illustration, chiaroscuro lighting, golden ratio, incredible art by artgerm and greg rutkowski and alphonse mucha and simon stalenhag -a highly detailed epic cinematic concept art CG render digital painting artwork: Steampunk Wizard stands and looks at the Tower of Babel in the distance. By Greg Rutkowski, in the style of Francis Bacon and Syd Mead and Norman Rockwell and Beksinski, open ceiling, highly detailed, painted by Francis Bacon and Edward Hopper, painted by James Gilleard, surrealism, airbrush, Ilya Kuvshinov, WLOP, Stanley Artgerm, very coherent, triadic color scheme, art by Takato Yamamoto and James Jean -devastated scorched earth in the valley, burnt trees, burnt vegetation and grass, cinematic view, epic sky, detailed, concept art, low angle, high detail, warm lighting, volumetric, godrays, vivid, beautiful, trending on artstation, by jordan grimmer, huge scene, grass, art greg rutkowski -portrait Ninja gaiden girl, armored black and red ninja wardrobe, in ruin japanese rainny temple night, ssci-fi and fantasy, intricate and very very beautiful and elegant, highly detailed, digital painting, artstation, concept art, smooth and sharp focus, illustration, art by tian zi and WLOP and alphonse mucha -girl jumping near a lake, rainy, touching a long neck monster, illustration concept art anime key visual trending pixiv fanbox by wlop and greg rutkowski and makoto shinkai and studio ghibli -beautiful digital painting of a hoyeon jung stylish female snow - covered mountains with high detail, real life skin, freckles, 8 k, stunning detail, works by artgerm, greg rutkowski and alphonse mucha, unreal engine 5, 4 k uhd -a potrait of a human rogue, fine details. night setting. realistic shaded lighting poster by ilya kuvshinov katsuhiro, artgerm, jeremy lipkin and michael garmash, unreal engine, radiant light, detailed and intricate environment, digital art, trending on art station -portrait full body girl 3 kingdom breathtaking detailed concept art painting art deco pattern of birds goddesses amalmation flowers head thibetan temple, by hsiao ron cheng, tetsuya ichida, bizarre compositions, tsutomu nihei, exquisite detail, extremely moody lighting, 8 k, art nouveau, old chines painting, art nouveau -greg manchess portrait painting of armored sanguinius with huge wings as overwatch character, medium shot, asymmetrical, profile picture, organic painting, sunny day, matte painting, bold shapes, hard edges, street art, trending on artstation, by huang guangjian and gil elvgren and sachin teng -rendering of old hands reaching forward, concept art, high detail, intimidating, cinematic, Artstation trending, octane render -dynamic photography portrait of a dungeons and dragons king's colosse , intricate ornate armor, subject in the middle of the frame, rule of thirds, golden ratio, elegant, digital painting, octane 4k render, zbrush, hyperrealistic, artstation, concept art, smooth, sharp focus, illustration from Warcraft by Ruan Jia and Mandy Jurgens and Artgerm and William-Adolphe Bouguerea -anthropomorphic triangle brain in edgy darkiron badger demon, intricate, elegant, highly detailed animal monster, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm, dwayne barlowe, trending on artstation and greg rutkowski and alphonse mucha, 8 k -christiano ronaldo, manga cover art, detailed color portrait, artstation trending, 8 k, greg rutkowski -a faceless!!!!! woman posing for the camera, charcoal painting!!!!! illustrated by kathe kollwitz, trending on artstation, 4 k, 8 k, artstation hd, artstation hq, artistic interpretation, 1 9 5 0 s style -a potrait of a female necromancer with big and cute eyes, fine - face, realistic shaded perfect face, fine details. night setting. very anime style. realistic shaded lighting poster by ilya kuvshinov katsuhiro, magali villeneuve, artgerm, jeremy lipkin and michael garmash, rob rey and kentaro miura style, trending on art station -fractal tarot card of a naturepunk retrofuture nexus of technology and earth, beautiful detailed realistic cinematic character high concept fashion portrait, hi - fructose art magazine, by anton fadeev and paul lehr and david heskin and josan gonzalez, 8 k -realistic high key portrait rendering of a beautiful curvy pale alabaster goth girl with asymmetrical punk rock hair and badass euro design sunglasses. mole on cheek. half portrait by stanley artgerm, dramatic lighting, by tohuvabohu, nagel, shin jeongho, nick silva and ilya kuvshinov, deviantart, detailed character design, 8 k resolution -the world serpent ultra detailed fantasy, elden ring, realistic, dnd character portrait, full body, dnd, rpg, lotr game design fanart by concept art, behance hd, artstation, deviantart, global illumination radiating a glowing aura global illumination ray tracing hdr render in unreal engine 5 -helmet of a forgotten deity with a labyrinth, in the style of tomasz alen kopera and fenghua zhong and peter mohrbacher, mystical colors, rim light, beautiful lighting, 8 k, stunning scene, raytracing, octane, trending on artstation -duotone psychedelic concept illustration 3 / 4 portrait of dr. albert hofmannn taking bicycle trip fractals background. cinematic scene. vlumetric lighting. golden rario accidental renaissance. by sachin teng and sergey kolesov and ruan jia and heng z. graffiti art, scifi, fantasy, hyper detailed. octane render. concept art. trending on artstation -A very tall, slender woman wearing black puffy clothes and holding a yellow umbrella, sharp focus, intricate, elegant, digital painting, artstation, matte, highly detailed, concept art, illustration, ambient lighting, art by artgerm, Alphonse mucha, and Greg Rutkowski -vibrant! colorful!!! the last supper of simpsons by rene magritte, futurama by laurie greasley and bouguereau, ( ( etching by gustave dore ) ), ultraclear intricate, sharp focus, highly detailed digital painting illustration, concept art, masterpiece -award winning brandmark for a research lab, mind wandering, hip corporate, no text, trendy, vector art, concept art -an epic non - binary model, subject made of white mesh rope, with cerulean and pastel pink bubbles bursting out, delicate, beautiful, intricate, melting into a wolf, houdini sidefx, by jeremy mann and ilya kuvshinov, jamie hewlett and ayami kojima, trending on artstation, bold 3 d -character concept of iridescent sinewy smooth muscular male sleek glossy indigo black pearlescent scifi armor with smooth black onyx featureless helmet, by greg rutkowski, mark brookes, jim burns, tom bagshaw, magali villeneuve, trending on artstation -phil noto, peter mohrbacher, thomas kinkade, artgerm, 1 9 5 0 s rockabilly anya taylor - joy catwoman dc comics, pompadour, long hair, vines, symmetrical eyes, city rooftop -dark high detailed space station interior a statue jesus on cross made of white marble, perfect symmetrical body, full body shot, inflateble shapes, wires, tubes, veins, jellyfish, white biomechanical details, wearing epic bionic cyborg implants, masterpiece, intricate, biopunk, vogue, highly detailed, artstation, concept art, cyberpunk, octane render -Portrait of a man by Greg Rutkowski, a young, strong and hard-eyed futuristic warrior with brown hair with dreadlocks, wearing a futuristic space tactical gear that looks like a mix between the samurai, viking and templar aesthetics, mix between tribal and hi-tech, highly detailed portrait, scifi, space opera, digital painting, artstation, concept art, smooth, sharp foccus ilustration, Artstation HQ -epic professional digital art of a snail in a blue professional business suit, sitting at a desk, best on artstation, cgsociety, wlop, Behance, pixiv, astonishing, impressive, outstanding, epic, cinematic, stunning, gorgeous, much detail, much wow, masterpiece -hyper realistic oil painting of frozen little island planet with waterfall, rising in the air, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -digitalart scifi!!! wallpaper trending on artstation -concept art of car designed by jony ive, jama jurabaev, science fiction, brush hard, artstation, cgsociety, high quality, brush stroke -A beautiful oil cartoony painting of a happy Remi Malek riding a tricycle by Lucas Graciano, Frank Frazetta, Greg Rutkowski, Boris Vallejo, epic fantasy character art, high fantasy, Exquisite detail, post-processing, low angle, masterpiece, cinematic -female priest in white cloak, ultra detailed fantasy, dndbeyond, bright, colourful, realistic, dnd character portrait, full body, pathfinder, pinterest, art by ralph horsley, dnd, rpg, lotr game design fanart by concept art, behance hd, artstation, deviantart, hdr render in unreal engine 5 -a beautiful portrait of death goddess by Greg Rutkowski and Raymond Swanland, ominous background, Trending on Artstation, ultra realistic digital art -cyborg drug addict, diffuse lighting, fantasy, intricate, elegant, highly detailed, lifelike, photorealistic, digital painting, artstation, illustration, concept art, smooth, sharp focus, art by John Collier and Albert Aublet and Krenz Cushart and Artem Demura and Alphonse Mucha -a well designed portrait of viper, detailed, realistic, sketch style, artstation, greg rutkowski, 8 k resolution. -Moira Stewart as Warhammer 40k Battle Sister, portrait, fantasy, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -hu tao from genshin impact, hu tao, perfect face, collaborative painting by greg ruthowski, ruan jia, artgerm, highly detailed, complex, exquisite and beautiful, 4 k, 8 k, artstation -rockstar girl playing electric guitar on stage. by amano yoshitaka, by rembrandt, digital art, digital painting, artstation trending, unreal engine -beautiful small cyberpunk robot-owl in the deep jungle, with neon color eyes, cinematic view, 8k, ultra realistic, vibrant colors, photo realism, trending artstation, octane render, volumetric lighting, high contrast, intricate, highly detailed, digital painting -john lennon as jack the ripper, ultra realistic, concept art, intricate details, highly detailed, photorealistic, octane render, 8 k, unreal engine, art by frank frazetta, simon bisley, brom -lux, from league of legends, au naturel, hyper detailed, digital art, trending in artstation, cinematic lighting, studio quality, smooth render, unreal engine 5 rendered, octane rendered, art style by klimt and nixeu and ian sprigger and wlop and krenz cushart -Anime art of beautiful Hatsune miku with beautifel legs by artgerm, ross tran, magali villeneuve, Greg Rutkowski, Gil Elvgren, Alberto Vargas, Earl Moran,, Art Frahm, Enoch Bolles -Daniel Radcliffe wearing a monks tunic holding a glowing fire magical staff. Trending on Artstation, octane render, ultra detailed, art by Ross tran -an super mega hyper realistic image of a super soldier with a Ukrainian blue and yellow stripes flag standing in the beam of light from the clouds on a pile of skulls as a winner, masculine figure, D&D, fantasy, intricate, elegant, highly detailed, extremely detailed, digital painting, artstation, concept art, matte, sharp focus, symmetrical, illustration, art by Artgerm and Greg Rutkowski and Alphonse Mucha -poster woman with futuristic streetwear and hairstyle, open jacket, cute face, symmetrical face, 3/4 angle, pretty, beautiful, elegant, Anime by Kuvshinov Ilya, Cushart Krentz and Gilleard James, 4k, HDR, Trending on artstation, Behance, Pinterest -man with fluffy pipidastr, atmosphere, glow, detailed, intricate, full of colour, cinematic lighting, trending on artstation, 4 k, hyperrealistic, focused, extreme details, unreal engine 5, cinematic, masterpiece, moody lighting, by greg rutkowski, wlop, artgerm, trending on artstation, concept art, sharp focus, ray tracing -a cinematic scene from the cthulhu in pyrrhic victory, concept art by beksinski and jean delville, dramatic lighting, ultra hd, hdr, 8 k -indistinct glowing prehistoric beasts surrounded by slate grey walls, insane details, dramatic lighting, unreal engine 5, concept art, greg rutkowski, james gurney, johannes voss, hasui kawase. -a full body portrait of a beautiful post apocalyptic offworld nordic desert snake charmer dancing playfully by the waterfalls, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by krenz cushart and artem demura and alphonse mucha -dia de los muertos theme poster art by artemio rodriguez, aida muluneh, and gustave bauman, intricate, accurate facial details, profile picture, artgerm, retro, nostalgic, old fashioned, posterized color -digital artwork, illustration, cinematic camera, a cyborg pilot in the cockpit of a mech, intricate machinery, biomechanics, the ghosts in the machine, cyberpunk concept art by artgerm and Guy Denning and Greg Rutkowski and Ruan Jia, highly detailed, intricate, sci-fi, sharp focus, Trending on Artstation HQ, deviantart -breathtaking detailed soft painting of a grim reaper with an intricate golden scythe and cloak of fireflies and embers, rembrandt style, detailed art nouveau stained glass of flames background, christian saint rosace, elegant, highly detailed, artstation, concept art, matte, sharp focus, art by Tom Bagshaw, Artgerm and Greg Rutkowski -portrait of mischievous, enigmatic!!, dangerous youngster Galadriel (Cate Blanchett) as a queen of elves, dressed in a refined silvery garment. The background is a dark, chilling eastern european forrest. night, horroristic shadows, blue tones, higher contrasts, (((lumnious))), theatrical, character concept art by ruan jia, (((thomas kinkade))), and J.Dickenson, trending on Pinterest, ArtStation -portrait painting of a bloodied serial killer wearing a hello kitty mask, ultra realistic, concept art, intricate details, eerie, highly detailed, photorealistic, octane render, 8 k, unreal engine. art by artgerm and greg rutkowski and alphonse mucha -An old man trapped in a cave, looking into a mirror, b&w, fantasy art, in the style of masami kurumada, illustration, epic, fantasy, intricate, hyper detailed, artstation, concept art, smooth, sharp focus, ray tracing -close-up macro portrait of the face of a beautiful princess with animal skull mask, epic angle and pose, ribcage bones symmetrical artwork, 3d with depth of field, blurred background, cybernetic jellyfish female face skull phoenix bird, translucent, nautilus, energy flows of water and fire. a highly detailed epic cinematic concept art CG render. made in Maya, Blender and Photoshop, octane render, excellent composition, cinematic dystopian brutalist atmosphere, dynamic dramatic cinematic lighting, aesthetic, very inspirational, arthouse. y Greg Rutkowski, Ilya Kuvshinov, WLOP, Stanley Artgerm Lau, Ruan Jia and Fenghua Zhong -poseidon humanoid god of the sea, trident, highly detailed, d & d, fantasy, highly detailed, digital painting, trending on artstation, concept art, sharp focus, illustration, art by artgerm and greg rutkowski and magali villeneuve -grainy and distorted xerox of a classified scientific government chart diagram a portal to a higher dimension photorealistic 4k photorealism realistic textures sharpened x-files fringe mystery sci-fi cinematic detailed texture hyperdetailed CIA agency NSA DOD government seal redacted continuous feed paper smooth, sharp focus, illustration, from Metal Gear, Greg Rutkowski and Artgerm artgerm -martin shkreli in attack on titan, medium shot close up, details, sharp focus, illustration, by jordan grimmer and greg rutkowski, trending artstation, pixiv, digital art -painting Daft Punk in long coat, elegant, intricate, headshot, highly detailed, digital painting, artstation, concept art, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -colleen moore 2 2 years old, bob haircut, portrait painted by stanley artgerm, casting long shadows, resting head on hands, by ross tran -hyper realistic photography of a stunningly beautiful sphere, self assembly, ribbons, glowing consciences, growing tendrils, hand in the style of beth cavener, jin kagetsu,, and wlop, highly detailed, intricate filigree, symmetry, masterpiece, award winning, sharp focus, concept art, highkey lighting, ambient lighting, octane render, 8 k, artstation -a photo of larry david playing poker while smoking highly detailed, dim volumetric lighting, 8k, post-processing, soft painting, trending on artstation, concept art, smooth, sharp focus, illustration,by Tom Bagshaw and Daniel Gerhartz and Albert Aublet and Lawrence Alma-Tadema and alphonse mucha -symmetry!! portrait of space soldier, tech wear, scifi, glowing lights!! intricate elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha -portrait of female android, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by fra angelico -jason fused with a poltergeist lovecraft nervous space demon, spiky skin, creepy, melting, big eyes, photo, portrait, 3 d, high details, intricate details, by vincent di fate, artgerm julie bell beeple, 9 0 s, smooth gradients, volumetric lightning, high contrast, duo tone, depth of field, very coherent symmetrical artwork -portrait of a fat blue alien. big friendly smile. character concept art. science fiction illustration. close up of the face. key panel art graphic novel. detailed face, beautiful colour palette. digital painting. -people with posters attacking cops in front a huge blue spiral - shaped white luminous attractor that is floating on the horizon near the sun and stores in los angeles with light screens all over the street, concept art, art for the game, professional lighting, dark night lighting from streetlights -Lofi cyberpunk portrait beautiful woman with short brown curly hair, roman face, Romanesque, unicorn, rainbow, floral, Pixar style, Tristan Eaton, Stanley Artgerm, Tom Bagshaw -dog eat dog world , made by Stanley Artgerm Lau, WLOP, Rossdraws, ArtStation, CGSociety, concept art, cgsociety, octane render, trending on artstation, artstationHD, artstationHQ, unreal engine, 4k, 8k, diff --git a/demo/Diffusion/demo_controlnet.py b/demo/Diffusion/demo_controlnet.py deleted file mode 100644 index 68ebc67b4..000000000 --- a/demo/Diffusion/demo_controlnet.py +++ /dev/null @@ -1,161 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("sd") - -import argparse - -import controlnet_aux -import torch -from cuda.bindings import runtime as cudart -from PIL import Image - -from demo_diffusion import dd_argparse -from demo_diffusion import image as image_module -from demo_diffusion import pipeline as pipeline_module - - -def parseArgs(): - parser = argparse.ArgumentParser(description="Options for Stable Diffusion ControlNet Demo", conflict_handler='resolve') - parser = dd_argparse.add_arguments(parser) - parser.add_argument('--scheduler', type=str, default="UniPC", choices=["DDIM", "DPM", "EulerA", "LMSD", "PNDM", "UniPC"], help="Scheduler for diffusion process") - parser.add_argument('--input-image', nargs = '+', type=str, default=[], help="Path to the input image/images already prepared for ControlNet modality. For example: canny edged image for canny ControlNet, not just regular rgb image") - parser.add_argument('--controlnet-type', nargs='+', type=str, default=["canny"], help="Controlnet type, can be `None`, `str` or `str` list from ['canny', 'depth', 'hed', 'mlsd', 'normal', 'openpose', 'scribble', 'seg']") - parser.add_argument('--controlnet-scale', nargs='+', type=float, default=[1.0], help="The outputs of the controlnet are multiplied by `controlnet_scale` before they are added to the residual in the original unet, can be `None`, `float` or `float` list") - return parser.parse_args() - -if __name__ == "__main__": - print("[I] Initializing StableDiffusion controlnet demo using TensorRT") - args = parseArgs() - - # Controlnet configuration - if not isinstance(args.controlnet_type, list): - raise ValueError(f"`--controlnet-type` must be of type `str` or `str` list, but is {type(args.controlnet_type)}") - - # Controlnet configuration - if not isinstance(args.controlnet_scale, list): - raise ValueError(f"`--controlnet-scale`` must be of type `float` or `float` list, but is {type(args.controlnet_scale)}") - - # Check number of ControlNets to ControlNet scales - if len(args.controlnet_type) != len(args.controlnet_scale): - raise ValueError(f"Numbers of ControlNets {len(args.controlnet_type)} should be equal to number of ControlNet scales {len(args.controlnet_scale)}.") - - # Convert controlnet scales to tensor - controlnet_scale = torch.FloatTensor(args.controlnet_scale) - - # Check images - input_images = [] - if len(args.input_image) > 0: - for image in args.input_image: - input_images.append(Image.open(image)) - else: - for controlnet in args.controlnet_type: - if controlnet == "canny": - if args.version == "xl-1.0": - canny_image = image_module.download_image( - "https://huggingface.co/diffusers/controlnet-canny-sdxl-1.0/resolve/main/out_bird.png" - ) - # "out_bird.png" has 5 images combined in a row. We pick the first image which is the input image. - canny_image = canny_image.crop((0, 0, canny_image.width / 5, canny_image.height)) - elif args.version == "1.5": - canny_image = image_module.download_image( - "https://hf.co/datasets/huggingface/documentation-images/resolve/main/diffusers/input_image_vermeer.png" - ) - canny_image = controlnet_aux.CannyDetector()(canny_image) - else: - raise ValueError( - f"This demo supports ControlNets for v1.4 and SDXL base pipelines only. Version provided: {args.version}" - ) - input_images.append(canny_image.resize((args.width, args.height))) - elif controlnet == "normal": - normal_image = image_module.download_image( - "https://huggingface.co/lllyasviel/sd-controlnet-normal/resolve/main/images/toy.png" - ) - normal_image = controlnet_aux.NormalBaeDetector.from_pretrained("lllyasviel/Annotators")(normal_image) - input_images.append(normal_image.resize((args.width, args.height))) - elif controlnet == "depth": - depth_image = image_module.download_image( - "https://huggingface.co/lllyasviel/sd-controlnet-depth/resolve/main/images/stormtrooper.png" - ) - depth_image = controlnet_aux.LeresDetector.from_pretrained("lllyasviel/Annotators")(depth_image) - input_images.append(depth_image.resize((args.width, args.height))) - elif controlnet == "hed": - hed_image = image_module.download_image( - "https://huggingface.co/lllyasviel/sd-controlnet-hed/resolve/main/images/man.png" - ) - hed_image = controlnet_aux.HEDdetector.from_pretrained("lllyasviel/Annotators")(hed_image) - input_images.append(hed_image.resize((args.width, args.height))) - elif controlnet == "mlsd": - mlsd_image = image_module.download_image( - "https://huggingface.co/lllyasviel/sd-controlnet-mlsd/resolve/main/images/room.png" - ) - mlsd_image = controlnet_aux.MLSDdetector.from_pretrained("lllyasviel/Annotators")(mlsd_image) - input_images.append(mlsd_image.resize((args.width, args.height))) - elif controlnet == "openpose": - openpose_image = image_module.download_image( - "https://huggingface.co/lllyasviel/sd-controlnet-openpose/resolve/main/images/pose.png" - ) - openpose_image = controlnet_aux.OpenposeDetector.from_pretrained("lllyasviel/Annotators")(openpose_image) - input_images.append(openpose_image.resize((args.width, args.height))) - elif controlnet == "scribble": - scribble_image = image_module.download_image( - "https://huggingface.co/lllyasviel/sd-controlnet-scribble/resolve/main/images/bag.png" - ) - scribble_image = controlnet_aux.HEDdetector.from_pretrained("lllyasviel/Annotators")(scribble_image, scribble=True) - input_images.append(scribble_image.resize((args.width, args.height))) - elif controlnet == "seg": - seg_image = image_module.download_image( - "https://huggingface.co/lllyasviel/sd-controlnet-seg/resolve/main/images/house.png" - ) - seg_image = controlnet_aux.SamDetector.from_pretrained("ybelkada/segment-anything", subfolder="checkpoints")(seg_image) - input_images.append(seg_image.resize((args.width, args.height))) - else: - raise ValueError(f"You should implement the conditonal image of this controlnet: {controlnet}") - assert len(input_images) > 0 - - kwargs_init_pipeline, kwargs_load_engine, args_run_demo = dd_argparse.process_pipeline_args(args) - - # Initialize demo - demo = pipeline_module.StableDiffusionPipeline( - pipeline_type=( - pipeline_module.PIPELINE_TYPE.CONTROLNET - if args.version != "xl-1.0" - else pipeline_module.PIPELINE_TYPE.XL_CONTROLNET - ), - controlnets=args.controlnet_type, - **kwargs_init_pipeline, - ) - - # Load TensorRT engines and pytorch modules - demo.loadEngines( - args.engine_dir, - args.framework_model_dir, - args.onnx_dir, - **kwargs_load_engine) - - # Load resources - _, shared_device_memory = cudart.cudaMalloc(demo.calculateMaxDeviceMemory()) - demo.activateEngines(shared_device_memory) - demo.loadResources(args.height, args.width, args.batch_size, args.seed) - - # Run inference - demo_kwargs = {'input_image': input_images, 'controlnet_scales': controlnet_scale} - demo.run(*args_run_demo, **demo_kwargs) - - demo.teardown() diff --git a/demo/Diffusion/demo_controlnet_sd35.py b/demo/Diffusion/demo_controlnet_sd35.py deleted file mode 100644 index 8dcb9869f..000000000 --- a/demo/Diffusion/demo_controlnet_sd35.py +++ /dev/null @@ -1,191 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("sd") - -import argparse - -import torch -from cuda.bindings import runtime as cudart -from PIL import Image - -from demo_diffusion import dd_argparse -from demo_diffusion import image as image_module -from demo_diffusion import pipeline as pipeline_module - - -def parseArgs(): - parser = argparse.ArgumentParser( - description="Options for Stable Diffusion 3.5-large ControlNet Demo", conflict_handler="resolve" - ) - parser = dd_argparse.add_arguments(parser) - parser.add_argument( - "--version", - type=str, - default="3.5-large", - choices={"3.5-large"}, - help="Version of Stable Diffusion 3.5", - ) - parser.add_argument("--height", type=int, default=1024, help="Height of image to generate (must be multiple of 8)") - parser.add_argument("--width", type=int, default=1024, help="Height of image to generate (must be multiple of 8)") - parser.add_argument( - "--max-sequence-length", - type=int, - default=256, - help="Maximum sequence length to use with the prompt.", - ) - parser.add_argument( - "--control-image", - nargs="+", - type=str, - default=[], - help="Path to the input image/images already prepared for ControlNet modality. For example: canny edged image for canny ControlNet, not just regular rgb image", - ) - parser.add_argument( - "--controlnet-type", - type=str, - default="canny", - help="Controlnet type (single type only), can be 'canny', 'depth', 'blur', etc.", - ) - parser.add_argument( - "--controlnet-scale", - type=float, - default=1.0, - help="The outputs of the controlnet are multiplied by `controlnet_scale` before they are added to the residual in the original Transformer", - ) - return parser.parse_args() - - -def process_demo_args(args): - batch_size = args.batch_size - prompt = args.prompt - negative_prompt = args.negative_prompt - # Process prompt - if not isinstance(prompt, list): - raise ValueError(f"`prompt` must be of type `str` list, but is {type(prompt)}") - prompt = prompt * batch_size - - if not isinstance(negative_prompt, list): - raise ValueError(f"`--negative-prompt` must be of type `str` list, but is {type(negative_prompt)}") - if len(negative_prompt) == 1: - negative_prompt = negative_prompt * batch_size - - if args.height % 8 != 0 or args.width % 8 != 0: - raise ValueError( - f"Image height and width have to be divisible by 8 but specified as: {args.image_height} and {args.width}." - ) - - max_batch_size = 4 - if args.batch_size > max_batch_size: - raise ValueError(f"Batch size {args.batch_size} is larger than allowed {max_batch_size}.") - - if args.use_cuda_graph and (not args.build_static_batch or args.build_dynamic_shape): - raise ValueError( - "Using CUDA graph requires static dimensions. Enable `--build-static-batch` and do not specify `--build-dynamic-shape`" - ) - - # Controlnet configuration - if not isinstance(args.controlnet_type, str): - raise ValueError(f"`--controlnet-type` must be of type `str`, but is {type(args.controlnet_type)}") - - # Controlnet configuration - if not isinstance(args.controlnet_scale, float): - raise ValueError(f"`--controlnet-scale` must be of type `float`, but is {type(args.controlnet_scale)}") - - # Convert controlnet scales to tensor - controlnet_scale = torch.tensor(args.controlnet_scale) - - # Check images - input_images = [] - if len(args.control_image) > 0: - for image in args.control_image: - input_images.append(Image.open(image)) - else: - if args.controlnet_type == "canny": - canny_image = image_module.download_image( - "https://huggingface.co/datasets/diffusers/diffusers-images-docs/resolve/main/canny.png" - ) - input_images.append(canny_image.resize((args.width, args.height))) - elif args.controlnet_type == "depth": - depth_image = image_module.download_image( - "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/marigold/marigold_einstein_lcm_depth.png" - ) - input_images.append(depth_image.resize((args.width, args.height))) - elif args.controlnet_type == "blur": - blur_image = image_module.download_image( - "https://huggingface.co/datasets/diffusers/diffusers-images-docs/resolve/main/blur.png" - ) - input_images.append(blur_image.resize((args.width, args.height))) - else: - raise ValueError(f"You should implement the conditonal image of this controlnet: {args.controlnet_type}") - assert len(input_images) > 0 - - kwargs_run_demo = { - "prompt": prompt, - "negative_prompt": negative_prompt, - "height": args.height, - "width": args.width, - "control_image": input_images, - "controlnet_scale": controlnet_scale, - "batch_count": args.batch_count, - "num_warmup_runs": args.num_warmup_runs, - "use_cuda_graph": args.use_cuda_graph, - } - - return kwargs_run_demo - - -if __name__ == "__main__": - print("[I] Initializing StableDiffusion ControlNet demo using TensorRT") - args = parseArgs() - - # Initialize demo - _, kwargs_load_engine, _ = dd_argparse.process_pipeline_args(args) - kwargs_run_demo = process_demo_args(args) - - # Initialize demo - demo = pipeline_module.StableDiffusion35Pipeline.FromArgs( - args, - pipeline_type=pipeline_module.PIPELINE_TYPE.CONTROLNET, - ) - - # Load TensorRT engines and pytorch modules - demo.load_engines( - framework_model_dir=args.framework_model_dir, - **kwargs_load_engine, - ) - - if demo.low_vram: - demo.device_memory_sizes = demo.get_device_memory_sizes() - else: - _, shared_device_memory = cudart.cudaMalloc(demo.calculate_max_device_memory()) - demo.activate_engines(shared_device_memory) - - # Load resources - demo.load_resources( - image_height=args.height, - image_width=args.width, - batch_size=args.batch_size, - seed=args.seed, - ) - - # Run inference - demo.run(**kwargs_run_demo) - - demo.teardown() diff --git a/demo/Diffusion/demo_diffusion/__init__.py b/demo/Diffusion/demo_diffusion/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/demo/Diffusion/demo_diffusion/dd_argparse.py b/demo/Diffusion/demo_diffusion/dd_argparse.py deleted file mode 100644 index a0be88244..000000000 --- a/demo/Diffusion/demo_diffusion/dd_argparse.py +++ /dev/null @@ -1,465 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -import argparse -from typing import Any, Dict, Tuple - -import torch - -# Define valid optimization levels for TensorRT engine build -VALID_OPTIMIZATION_LEVELS = list(range(6)) - - -def parse_key_value_pairs(string: str) -> Dict[str, str]: - """Parse a string of comma-separated key-value pairs into a dictionary. - - Args: - string (str): A string of comma-separated key-value pairs. - - Returns: - Dict[str, str]: Parsed dictionary of key-value pairs. - - Example: - >>> parse_key_value_pairs("key1:value1,key2:value2") - {"key1": "value1", "key2": "value2"} - """ - parsed = {} - - for key_value_pair in string.split(","): - if not key_value_pair: - continue - - key_value_pair = key_value_pair.split(":") - if len(key_value_pair) != 2: - raise argparse.ArgumentTypeError(f"Invalid key-value pair: {key_value_pair}. Must have length 2.") - key, value = key_value_pair - parsed[key] = value - - return parsed - - -def add_arguments(parser): - # Stable Diffusion configuration - parser.add_argument( - "--version", - type=str, - default="1.4", - choices=( - "1.4", - "dreamshaper-7", - "xl-1.0", - "xl-turbo", - "svd-xt-1.1", - "sd3", - "3.5-medium", - "3.5-large", - "cascade", - "flux.1-dev", - "flux.1-schnell", - "flux.1-dev-canny", - "flux.1-dev-depth", - "flux.1-kontext-dev", - "cosmos-predict2-2b-text2image", - "cosmos-predict2-14b-text2image", - "cosmos-predict2-2b-video2world", - "cosmos-predict2-14b-video2world", - ), - help="Version of Stable Diffusion", - ) - parser.add_argument("prompt", nargs="*", help="Text prompt(s) to guide image generation") - parser.add_argument( - "--negative-prompt", nargs="*", default=[""], help="The negative prompt(s) to guide the image generation." - ) - parser.add_argument("--batch-size", type=int, default=1, choices=[1, 2, 4], help="Batch size (repeat prompt)") - parser.add_argument( - "--batch-count", type=int, default=1, help="Number of images to generate in sequence, one at a time." - ) - parser.add_argument("--height", type=int, default=512, help="Height of image to generate (must be multiple of 8)") - parser.add_argument("--width", type=int, default=512, help="Height of image to generate (must be multiple of 8)") - parser.add_argument("--denoising-steps", type=int, default=30, help="Number of denoising steps") - parser.add_argument( - "--scheduler", - type=str, - default=None, - choices=("DDIM", "DDPM", "EulerA", "Euler", "LCM", "LMSD", "PNDM", "UniPC", "DDPMWuerstchen", "FlowMatchEuler"), - help="Scheduler for diffusion process", - ) - parser.add_argument( - "--guidance-scale", - type=float, - default=7.5, - help="Value of classifier-free guidance scale (must be greater than 1)", - ) - parser.add_argument( - "--lora-scale", - type=float, - default=1.0, - help="Controls how much to influence the outputs with the LoRA parameters. (must between 0 and 1)", - ) - parser.add_argument( - "--lora-weight", - type=float, - nargs="+", - default=None, - help="The LoRA adapter(s) weights to use with the UNet. (must between 0 and 1)", - ) - parser.add_argument( - "--lora-path", - type=str, - nargs="+", - default=None, - help="Path to LoRA adaptor. Ex: 'latent-consistency/lcm-lora-sdv1-5'", - ) - parser.add_argument("--bf16", action="store_true", help="Run pipeline in BFloat16 precision") - - # ONNX export - parser.add_argument( - "--onnx-opset", - type=int, - default=19, - choices=range(7, 24), - help="Select ONNX opset version to target for exported models", - ) - parser.add_argument("--onnx-dir", default="onnx", help="Output directory for ONNX export") - parser.add_argument( - "--custom-onnx-paths", - type=parse_key_value_pairs, - help=( - "[FLUX, Stable Diffusion 3.5-large, Cosmos only] Custom override paths to pre-exported ONNX model files. These ONNX models are directly used to " - "build TRT engines without further optimization on the ONNX graphs. Paths should be a comma-separated list " - "of : pairs. For example: " - "--custom-onnx-paths=transformer:/path/to/transformer.onnx,vae:/path/to/vae.onnx. Call " - ".get_model_names(...) for the list of supported model names." - ), - ) - parser.add_argument( - "--onnx-export-only", - action="store_true", - help="If set, only performs the export of models to ONNX, skipping engine build and inference.", - ) - parser.add_argument( - "--download-onnx-models", - action="store_true", - help=("[FLUX and Stable Diffusion 3.5-large only] Download pre-exported ONNX models"), - ) - - # Framework model ckpt - parser.add_argument("--framework-model-dir", default="pytorch_model", help="Directory for HF saved models") - - # TensorRT engine build - parser.add_argument("--engine-dir", default="engine", help="Output directory for TensorRT engines") - parser.add_argument( - "--custom-engine-paths", - type=parse_key_value_pairs, - help=( - "[FLUX only] Custom override paths to pre-built engine files. Paths should be a comma-separated list of " - ": pairs. For example: " - "--custom-onnx-paths=transformer:/path/to/transformer.plan,vae:/path/to/vae.plan. Call " - ".get_model_names(...) for the list of supported model names." - ), - ) - - parser.add_argument( - "--optimization-level", - type=int, - default=None, - help=f"Set the builder optimization level to build the engine with. A higher level allows TensorRT to spend more building time for more optimization options. Must be one of {VALID_OPTIMIZATION_LEVELS}.", - ) - parser.add_argument( - "--build-static-batch", action="store_true", help="Build TensorRT engines with fixed batch size." - ) - parser.add_argument( - "--build-dynamic-shape", action="store_true", help="Build TensorRT engines with dynamic image shapes." - ) - parser.add_argument( - "--build-enable-refit", action="store_true", help="Enable Refit option in TensorRT engines during build." - ) - parser.add_argument( - "--build-all-tactics", action="store_true", help="Build TensorRT engines using all tactic sources." - ) - parser.add_argument( - "--timing-cache", default=None, type=str, help="Path to the precached timing measurements to accelerate build." - ) - parser.add_argument("--ws", action="store_true", help="Build TensorRT engines with weight streaming enabled.") - - # Quantization configuration. - parser.add_argument("--int8", action="store_true", help="Apply int8 quantization.") - parser.add_argument("--fp8", action="store_true", help="Apply fp8 quantization.") - parser.add_argument("--fp4", action="store_true", help="Apply fp4 quantization.") - parser.add_argument( - "--quantization-level", - type=float, - default=0.0, - choices=[0.0, 1.0, 2.0, 2.5, 3.0, 4.0], - help="int8/fp8 quantization level, 1: CNN, 2: CNN + FFN, 2.5: CNN + FFN + QKV, 3: CNN + Almost all Linear (Including FFN, QKV, Proj and others), 4: CNN + Almost all Linear + fMHA, 0: Default to 2.5 for int8 and 4.0 for fp8.", - ) - parser.add_argument( - "--quantization-percentile", - type=float, - default=1.0, - help="Control quantization scaling factors (amax) collecting range, where the minimum amax in range(n_steps * percentile) will be collected. Recommendation: 1.0.", - ) - parser.add_argument( - "--quantization-alpha", - type=float, - default=0.8, - help="The alpha parameter for SmoothQuant quantization used for linear layers. Recommendation: 0.8 for SDXL.", - ) - parser.add_argument( - "--calibration-size", - type=int, - default=32, - help="The number of steps to use for calibrating the model for quantization. Recommendation: 32, 64, 128 for SDXL", - ) - - # Inference - parser.add_argument( - "--num-warmup-runs", type=int, default=5, help="Number of warmup runs before benchmarking performance" - ) - parser.add_argument("--use-cuda-graph", action="store_true", help="Enable cuda graph") - parser.add_argument("--nvtx-profile", action="store_true", help="Enable NVTX markers for performance profiling") - parser.add_argument( - "--torch-inference", - default="", - help="Run inference with PyTorch (using specified compilation mode) instead of TensorRT.", - ) - parser.add_argument( - "--torch-fallback", - default=None, - type=str, - help="[FLUX, SD3.5, and Wan] Comma separated list of models to be inferenced using PyTorch instead of TRT. For example --torch-fallback text_encoder,transformer,transformer_2. If --torch-inference set, this parameter will be ignored.", - ) - parser.add_argument( - "--low-vram", - action="store_true", - help="[FLUX, SD3.5, and Wan] Optimize for low VRAM usage, possibly at the expense of inference performance. Disabled by default.", - ) - parser.add_argument("--seed", type=int, default=None, help="Seed for random generator to get consistent results") - parser.add_argument("--output-dir", default="output", help="Output directory for logs and image artifacts") - parser.add_argument("--hf-token", type=str, help="HuggingFace API access token for downloading model checkpoints") - parser.add_argument("-v", "--verbose", action="store_true", help="Show verbose output") - return parser - - -def process_pipeline_args(args: argparse.Namespace) -> Tuple[Dict[str, Any], Dict[str, Any], Tuple]: - """Validate parsed arguments and process argument values. - - Some argument values are resolved or overwritten during processing. - - Args: - args (argparse.Namespace): Parsed argument. This is modified in-place. - - Returns: - Dict[str, Any]: Keyword arguments for initializing a pipeline. This is only used in legacy pipelines that do not - have factory methods `FromArgs` that construct the pipeline directly from the parsed argument. - Dict[str, Any]: Keyword arguments for calling the `.load_engine` method of the pipeline. - Tuple: Arguments for calling the `.run` method of the pipeline. - """ - - # GPU device info - device_info = torch.cuda.get_device_properties(0) - sm_version = device_info.major * 10 + device_info.minor - - is_flux = args.version.startswith("flux") - is_sd35 = args.version.startswith("3.5") - is_wan = args.version.startswith("wan") - is_cosmos = args.version.startswith("cosmos") - - if args.height % 8 != 0 or args.width % 8 != 0: - raise ValueError( - f"Image height and width have to be divisible by 8 but specified as: {args.image_height} and {args.width}." - ) - - # Handle batch size - max_batch_size = 4 - if args.batch_size > max_batch_size: - raise ValueError(f"Batch size {args.batch_size} is larger than allowed {max_batch_size}.") - - if args.use_cuda_graph and (not args.build_static_batch or args.build_dynamic_shape): - raise ValueError( - "Using CUDA graph requires static dimensions. Enable `--build-static-batch` and do not specify `--build-dynamic-shape`" - ) - - # TensorRT builder optimization level - if args.optimization_level is None: - # optimization level set to 3 for all Flux pipelines to reduce GPU memory usage - if args.int8 or args.fp8 and not is_flux: - args.optimization_level = 4 - else: - args.optimization_level = 3 - - if args.optimization_level not in VALID_OPTIMIZATION_LEVELS: - raise ValueError( - f"Optimization level {args.optimization_level} not valid. Valid values are: {VALID_OPTIMIZATION_LEVELS}" - ) - - # Quantized pipeline - # int8 support - if args.int8 and not any(args.version.startswith(prefix) for prefix in ("xl", "1.4")): - raise ValueError("int8 quantization is only supported for SDXL and SD1.4 pipelines.") - - # fp8 support validation - if args.fp8: - # Check version compatibility - supported_versions = ("xl", "1.4", "3.5-large") - if not (any(args.version.startswith(prefix) for prefix in supported_versions) or is_flux): - raise ValueError( - "fp8 quantization is only supported for SDXL, SD1.4, SD3.5-large and FLUX pipelines." - ) - - # Check controlnet compatibility - if getattr(args, "controlnet_type", None) is not None: - if args.version not in ("xl-1.0", "3.5-large"): - raise ValueError("fp8 controlnet quantization is only supported for SDXL and SD3.5-large.") - if args.version == "3.5-large" and args.controlnet_type == "blur": - raise ValueError("Blur controlnet type is not supported for SD3.5.") - # Check for conflicting quantization - if args.int8: - raise ValueError("Cannot apply both int8 and fp8 quantization, please choose only one.") - - # Check GPU compute capability - if sm_version < 89: - raise ValueError( - f"Cannot apply FP8 quantization for GPU with compute capability {sm_version / 10.0}. A minimum compute capability of 8.9 is required." - ) - - # Check SD3.5-large specific requirement - if args.version == "3.5-large" and not args.download_onnx_models: - raise ValueError( - "Native FP8 quantization is not supported for SD3.5-large. Please pass --download-onnx-models." - ) - - # TensorRT ModelOpt quantization level - if args.quantization_level == 0.0: - def override_quant_level(level: float, dtype_str: str): - args.quantization_level = level - print(f"[W] The default quantization level has been set to {level} for {dtype_str}.") - - if args.fp8: - # L4 fp8 fMHA on Hopper not yet enabled. - if sm_version == 90 and is_flux: - override_quant_level(3.0, "FP8") - else: - override_quant_level(3.0 if args.version == "1.4" else 4.0, "FP8") - - elif args.int8: - override_quant_level(3.0, "INT8") - - if args.version.startswith("flux") and args.quantization_level == 3.0 and args.download_onnx_models: - raise ValueError( - "Transformer ONNX model for Quantization level 3 is not available for download. Please export the quantized Transformer model natively with the removal of --download-onnx-models." - ) - if args.fp4: - # FP4 precision is only supported for the Flux pipeline - assert is_flux, "FP4 precision is only supported for the Flux pipeline" - - # Handle LoRA - # FLUX canny and depth official LoRAs are not supported because they modify the transformer architecture, conflicting with refit - if args.lora_path and not any(args.version.startswith(prefix) for prefix in ("xl", "flux.1-dev", "flux.1-schnell")): - raise ValueError("LoRA adapter support is only supported for SDXL, FLUX.1-dev and FLUX.1-schnell pipelines") - - if args.lora_weight: - for weight in (weight for weight in args.lora_weight if not 0 <= weight <= 1): - raise ValueError(f"LoRA adapter weights must be between 0 and 1, provided {weight}") - - if not 0 <= args.lora_scale <= 1: - raise ValueError(f"LoRA scale value must be between 0 and 1, provided {args.lora_scale}") - - # Force lora merge when fp8 or int8 is used with LoRA - if args.build_enable_refit and args.lora_path and (args.int8 or args.fp8): - raise ValueError( - "Engine refit should not be enabled for quantized models with LoRA. ModelOpt recommends fusing the LoRA to the model before quantization. \ - See https://github.com/NVIDIA/TensorRT-Model-Optimizer/tree/main/examples/diffusers/quantization#lora" - ) - - # Torch-fallback and Torch-inference - if args.torch_fallback and not args.torch_inference: - assert ( - is_flux or is_sd35 or is_wan or is_cosmos - ), "PyTorch Fallback is only supported for Flux, Stable Diffusion 3.5, Wan and Cosmos pipelines." - args.torch_fallback = args.torch_fallback.split(",") - - if args.torch_fallback and args.torch_inference: - print( - "[W] All models will run in PyTorch when --torch-inference is set. Parameter --torch-fallback will be ignored." - ) - args.torch_fallback = None - - # low-vram - if args.low_vram: - assert ( - is_flux or is_sd35 or is_wan or is_cosmos - ), "low-vram mode is only supported for Flux, Stable Diffusion 3.5, Wan and Cosmos pipelines." - - # Disable SDXL LCM pipeline - if args.version == "xl-1.0" and args.scheduler == "LCM": - raise ValueError("SDXL pipeline does not support the LCM scheduler currently. Please use a different scheduler.") - - # Pack arguments - kwargs_init_pipeline = { - "version": args.version, - "max_batch_size": max_batch_size, - "denoising_steps": args.denoising_steps, - "scheduler": args.scheduler, - "guidance_scale": args.guidance_scale, - "output_dir": args.output_dir, - "hf_token": args.hf_token, - "verbose": args.verbose, - "nvtx_profile": args.nvtx_profile, - "use_cuda_graph": args.use_cuda_graph, - "lora_scale": args.lora_scale, - "lora_weight": args.lora_weight, - "lora_path": args.lora_path, - "framework_model_dir": args.framework_model_dir, - "torch_inference": args.torch_inference, - } - - kwargs_load_engine = { - "onnx_opset": args.onnx_opset, - "opt_batch_size": args.batch_size, - "opt_image_height": args.height, - "opt_image_width": args.width, - "optimization_level": args.optimization_level, - "static_batch": args.build_static_batch, - "static_shape": not args.build_dynamic_shape, - "enable_all_tactics": args.build_all_tactics, - "enable_refit": args.build_enable_refit, - "timing_cache": args.timing_cache, - "int8": args.int8, - "fp8": args.fp8, - "fp4": args.fp4, - "quantization_level": args.quantization_level, - "quantization_percentile": args.quantization_percentile, - "quantization_alpha": args.quantization_alpha, - "calibration_size": args.calibration_size, - "onnx_export_only": args.onnx_export_only, - "download_onnx_models": args.download_onnx_models, - } - - args_run_demo = ( - args.prompt, - args.negative_prompt, - args.height, - args.width, - args.batch_size, - args.batch_count, - args.num_warmup_runs, - args.use_cuda_graph, - ) - - return kwargs_init_pipeline, kwargs_load_engine, args_run_demo diff --git a/demo/Diffusion/demo_diffusion/deps.py b/demo/Diffusion/demo_diffusion/deps.py deleted file mode 100644 index b50c7ca12..000000000 --- a/demo/Diffusion/demo_diffusion/deps.py +++ /dev/null @@ -1,270 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -"""Dependency management for TensorRT diffusion demos. - -Adds the right group's site-packages to sys.path so imports work. -""" - -import os -import sys - -# Marker file to indicate successful installation -# Must match the marker file used by setup.py -INSTALL_COMPLETE_MARKER = ".install_complete" - -# Descriptions for user-facing messages -GROUP_DESCRIPTIONS = { - "sd": "SD family (SD 1.4, SDXL, SD3, SD3.5, SVD, Stable Cascade)", - "flux": "Flux family (Black Forest Labs)", - "cosmos": "Cosmos family (NVIDIA), Wan2.2 T2V", -} - -# Valid dependency groups -VALID_GROUPS = list(GROUP_DESCRIPTIONS.keys()) - -__all__ = [ - "configure", - "get_configured_groups", - "print_status", -] - - -def _resolve_deps_root(deps_root: str | None) -> str: - """Resolve the dependency root path with precedence: arg > env > default.""" - if deps_root is not None: - return deps_root - return os.environ.get("TENSORRT_DIFFUSION_DEPS_ROOT", "/workspace/deps") - -def _prepend_env_path(var: str, path: str, clean_root: str | None = None): - """Prepend `path` to an os.pathsep-separated env var so child processes - (e.g. the `polygraphy` CLI) inherit the group's dependencies. If - `clean_root` is given, drop existing entries under it first.""" - def _norm(p: str) -> str: - return os.path.abspath(os.path.expanduser(p)) - - existing = [p for p in os.environ.get(var, "").split(os.pathsep) if p] - if clean_root is not None: - root_abs = _norm(clean_root).rstrip(os.sep) + os.sep - existing = [p for p in existing if not _norm(p).startswith(root_abs)] - existing = [p for p in existing if _norm(p) != _norm(path)] - os.environ[var] = os.pathsep.join([path, *existing]) - - -def _clean_diffusion_paths(deps_root: str = "/workspace/deps"): - """Drop any existing paths under deps_root from sys.path.""" - # Filter out any paths that live under deps_root (robust to path forms) - root_abs = os.path.abspath(os.path.expanduser(deps_root)).rstrip(os.sep) + os.sep - sys.path[:] = [ - p for p in sys.path - if not os.path.abspath(os.path.expanduser(p)).startswith(root_abs) - ] - - -def configure( - group: str, - deps_root: str | None = None, - verbose: bool = False, - clean: bool = True, - fallback: bool = False -): - """ - Configure sys.path to use dependencies from the specified group. - - This function should be called at the top of each demo script, before - any other imports that depend on external packages. - - Args: - group: Dependency group name ("sd", "flux", or "cosmos") - deps_root: Root directory where dependencies are installed. - If None, uses TENSORRT_DIFFUSION_DEPS_ROOT environment variable, - or defaults to "/workspace/deps" - verbose: Print configuration info (default: False) - clean: Remove other dependency group paths first (default: True) - This prevents sys.path inflation in long-running processes. - fallback: If True, gracefully handle missing dependencies instead of raising - RuntimeError. Useful for test environments using requirements.txt. - If False but USE_REQUIREMENTS=1 is set, - fallback will be automatically enabled. - - Example: - from demo_diffusion import deps - deps.configure("flux") - - # Or with custom location - deps.configure("flux", deps_root="/custom/path/deps") - - # Or via environment variable - # export TENSORRT_DIFFUSION_DEPS_ROOT=/custom/path/deps - # deps.configure("flux") - - # For test environments using requirements.txt (installed via setup.sh) - # export USE_REQUIREMENTS=1 - # deps.configure("sd") # Will automatically use fallback mode - """ - if group not in VALID_GROUPS: - raise ValueError( - f"Invalid dependency group: '{group}'\n" - f"Valid groups: {', '.join(sorted(VALID_GROUPS))}" - ) - - # Auto-enable fallback mode if using requirements.txt installation - if not fallback and os.environ.get("USE_REQUIREMENTS") == "1": - fallback = True - if verbose: - print("Detected USE_REQUIREMENTS=1, enabling fallback mode") - - # Resolve deps_root consistently across the module - deps_root = _resolve_deps_root(deps_root) - - # Clean old dependency paths first (prevents inflation) - if clean: - _clean_diffusion_paths(deps_root) - - # Determine Python version - python_version = f"{sys.version_info.major}.{sys.version_info.minor}" - - # Construct path to site-packages for this group - deps_path = os.path.join( - deps_root, - group, - "lib", - f"python{python_version}", - "site-packages" - ) - - # Check if installation is complete - group_dir = os.path.join(deps_root, group) - marker_file = os.path.join(group_dir, INSTALL_COMPLETE_MARKER) - - if os.path.exists(deps_path) and os.path.exists(marker_file): - # Insert at the beginning to override any system packages - sys.path.insert(0, deps_path) - - # Mirror onto the environment so child processes (e.g. the polygraphy - # CLI that engine builds shell out to) use these deps too. When clean, - # drop other groups' entries under deps_root, matching sys.path above. - clean_root = deps_root if clean else None - _prepend_env_path("PYTHONPATH", deps_path, clean_root=clean_root) - _prepend_env_path("PATH", os.path.join(group_dir, "bin"), clean_root=clean_root) - - if verbose: - description = GROUP_DESCRIPTIONS.get(group, group) - print(f"Configured dependencies: {description}") - print(f" Path: {deps_path}") - else: - # Dependencies not found or installation incomplete - description = GROUP_DESCRIPTIONS.get(group, group) - - # Check if it's an incomplete installation - if os.path.exists(group_dir) and not os.path.exists(marker_file): - error_msg = ( - f"Dependencies for '{group}' are incomplete!\n" - f" Location: {group_dir}\n" - f" Description: {description}\n" - f" A previous installation failed or was interrupted.\n" - f" To fix, run:\n" - f" python setup.py {group}\n" - f" (This will clean up and reinstall)" - ) - if fallback: - if verbose: - print(f"Warning: {error_msg}") - print("Continuing with fallback mode...") - return - else: - raise RuntimeError(error_msg) - else: - # Not installed at all - error_msg = ( - f"Dependencies for '{group}' not found!\n" - f" Expected at: {deps_path}\n" - f" Description: {description}\n" - f" To install, run: python setup.py {group}\n" - f" If you installed elsewhere, set TENSORRT_DIFFUSION_DEPS_ROOT or pass deps_root." - ) - if fallback: - if verbose: - print(f"Warning: {error_msg}") - print("Continuing with fallback mode (assuming requirements.txt setup)...") - return - else: - raise RuntimeError(error_msg) - - -def get_configured_groups(deps_root: str | None = None) -> list[str]: - """ - Get list of dependency groups that are currently installed. - - A group is considered installed only if both: - 1. The group directory exists - 2. The .install_complete marker file exists in that directory - - Args: - deps_root: Root directory where dependencies are installed. - If None, uses TENSORRT_DIFFUSION_DEPS_ROOT environment variable, - or defaults to "/workspace/deps" - - Returns: - List of installed group names (e.g., ["sd", "flux"]) - """ - # Resolve deps_root - deps_root = _resolve_deps_root(deps_root) - - installed = [] - for group in VALID_GROUPS: - # Check if the group directory exists and has the completion marker - group_dir = os.path.join(deps_root, group) - marker_file = os.path.join(group_dir, INSTALL_COMPLETE_MARKER) - - # Only consider it installed if marker file exists - if os.path.exists(group_dir) and os.path.isdir(group_dir) and os.path.exists(marker_file): - installed.append(group) - return sorted(installed) - - -def print_status(deps_root: str | None = None): - """ - Print the status of all dependency groups. - - Args: - deps_root: Root directory where dependencies are installed. - If None, uses TENSORRT_DIFFUSION_DEPS_ROOT environment variable, - or defaults to "/workspace/deps" - """ - # Resolve deps_root - deps_root = _resolve_deps_root(deps_root) - - print("Dependency Groups Status:") - print("-" * 60) - print(f"Location: {deps_root}") - print("-" * 60) - - installed = get_configured_groups(deps_root) - - for group in sorted(VALID_GROUPS): - description = GROUP_DESCRIPTIONS.get(group, group) - status = "Installed" if group in installed else "Not installed" - print(f" {group:8} - {status:15} - {description}") - - print("-" * 60) - - if not installed: - print("No dependency groups installed.") - print("Run: python setup.py all") - else: - print(f"{len(installed)} group(s) installed: {', '.join(installed)}") diff --git a/demo/Diffusion/demo_diffusion/dynamic_import.py b/demo/Diffusion/demo_diffusion/dynamic_import.py deleted file mode 100755 index 42a1ddd6c..000000000 --- a/demo/Diffusion/demo_diffusion/dynamic_import.py +++ /dev/null @@ -1,30 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import warnings -from importlib import import_module - - -def import_from_diffusers(model_name, module_name): - try: - module = import_module(module_name) - return getattr(module, model_name) - except ImportError: - warnings.warn(f"Failed to import {module_name}. The {model_name} model will not be available.", ImportWarning) - except AttributeError: - warnings.warn(f"The {model_name} model is not available in the installed version of diffusers.", ImportWarning) - return None diff --git a/demo/Diffusion/demo_diffusion/engine.py b/demo/Diffusion/demo_diffusion/engine.py deleted file mode 100644 index 9dc8feeea..000000000 --- a/demo/Diffusion/demo_diffusion/engine.py +++ /dev/null @@ -1,326 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import gc -import os -import subprocess -import warnings -from collections import OrderedDict, defaultdict - -import numpy as np -import onnx -import tensorrt as trt -import torch -from cuda.bindings import runtime as cudart -from onnx import numpy_helper -from polygraphy.backend.common import bytes_from_path -from polygraphy.backend.trt import ( - engine_from_bytes, -) - -TRT_LOGGER = trt.Logger(trt.Logger.ERROR) - - -# Map of TensorRT dtype -> torch dtype -trt_to_torch_dtype_dict = { - trt.DataType.BOOL: torch.bool, - trt.DataType.UINT8: torch.uint8, - trt.DataType.INT8: torch.int8, - trt.DataType.INT32: torch.int32, - trt.DataType.INT64: torch.int64, - trt.DataType.HALF: torch.float16, - trt.DataType.FLOAT: torch.float32, - trt.DataType.BF16: torch.bfloat16, -} - - -def _CUASSERT(cuda_ret): - err = cuda_ret[0] - if err != cudart.cudaError_t.cudaSuccess: - raise RuntimeError( - f"CUDA ERROR: {err}, error code reference: https://nvidia.github.io/cuda-python/module/cudart.html#cuda.cudart.cudaError_t" - ) - if len(cuda_ret) > 1: - return cuda_ret[1] - return None - - -def get_refit_weights(state_dict, onnx_opt_path, weight_name_mapping, weight_shape_mapping): - onnx_opt_dir = os.path.dirname(onnx_opt_path) - onnx_opt_model = onnx.load(onnx_opt_path) - # Create initializer data hashes - initializer_hash_mapping = {} - for initializer in onnx_opt_model.graph.initializer: - initializer_data = numpy_helper.to_array(initializer, base_dir=onnx_opt_dir).astype(np.float16) - initializer_hash = hash(initializer_data.data.tobytes()) - initializer_hash_mapping[initializer.name] = initializer_hash - - refit_weights = OrderedDict() - updated_weight_names = set() # save names of updated weights to refit only the required weights - for wt_name, wt in state_dict.items(): - # query initializer to compare - initializer_name = weight_name_mapping[wt_name] - initializer_hash = initializer_hash_mapping[initializer_name] - - # get shape transform info - initializer_shape, is_transpose = weight_shape_mapping[wt_name] - if is_transpose: - wt = torch.transpose(wt, 0, 1) - else: - wt = torch.reshape(wt, initializer_shape) - - # include weight if hashes differ - wt_hash = hash(wt.cpu().detach().numpy().astype(np.float16).data.tobytes()) - if initializer_hash != wt_hash: - updated_weight_names.add(initializer_name) - # Store all weights as the refitter may require unchanged weights too - # docs: https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html#refitting-engine-c - refit_weights[initializer_name] = wt.contiguous() - return refit_weights, updated_weight_names - - -class Engine: - def __init__( - self, - engine_path, - ): - self.engine_path = engine_path - self.engine = None - self.context = None - self.buffers = OrderedDict() - self.tensors = OrderedDict() - self.cuda_graph_instance = None # cuda graph - - def __del__(self): - del self.engine - del self.context - del self.buffers - del self.tensors - - def refit(self, refit_weights, updated_weight_names): - # Initialize refitter - refitter = trt.Refitter(self.engine, TRT_LOGGER) - refitted_weights = set() - - def refit_single_weight(trt_weight_name): - # get weight from state dict - trt_datatype = refitter.get_weights_prototype(trt_weight_name).dtype - refit_weights[trt_weight_name] = refit_weights[trt_weight_name].to(trt_to_torch_dtype_dict[trt_datatype]) - - # trt.Weight and trt.TensorLocation - trt_wt_tensor = trt.Weights( - trt_datatype, refit_weights[trt_weight_name].data_ptr(), torch.numel(refit_weights[trt_weight_name]) - ) - trt_wt_location = ( - trt.TensorLocation.DEVICE if refit_weights[trt_weight_name].is_cuda else trt.TensorLocation.HOST - ) - - # apply refit - refitter.set_named_weights(trt_weight_name, trt_wt_tensor, trt_wt_location) - refitted_weights.add(trt_weight_name) - - # iterate through all tensorrt refittable weights - for trt_weight_name in refitter.get_all_weights(): - if trt_weight_name not in updated_weight_names: - continue - - refit_single_weight(trt_weight_name) - - # iterate through missing weights required by tensorrt - addresses the case where lora_scale=0 - for trt_weight_name in refitter.get_missing_weights(): - refit_single_weight(trt_weight_name) - - if not refitter.refit_cuda_engine(): - print("Error: failed to refit new weights.") - exit(0) - - print(f"[I] Total refitted weights {len(refitted_weights)}.") - - def build( - self, - onnx_path, - tf32=False, - input_profile=None, - enable_refit=False, - enable_all_tactics=False, - timing_cache=None, - update_output_names=None, - native_instancenorm=True, - verbose=False, - weight_streaming=False, - builder_optimization_level=3, - precision_constraints='none', - ): - print(f"Building TensorRT engine for {onnx_path}: {self.engine_path}") - - # Base command - build_command = [f"polygraphy convert {onnx_path} --convert-to trt --output {self.engine_path}"] - - # Build arguments - build_args = [ - "--strongly-typed", - "--tf32" if tf32 else "", - "--weight-streaming" if weight_streaming else "", - "--refittable" if enable_refit else "", - "--tactic-sources" if not enable_all_tactics else "", - "--onnx-flags native_instancenorm" if native_instancenorm else "", - f"--builder-optimization-level {builder_optimization_level}", - f"--precision-constraints {precision_constraints}", - ] - - # Timing cache - if timing_cache: - build_args.extend([ - f"--load-timing-cache {timing_cache}", - f"--save-timing-cache {timing_cache}" - ]) - - # Verbosity setting - verbosity = "extra_verbose" if verbose else "error" - build_args.append(f"--verbosity {verbosity}") - - # Output names - if update_output_names: - print(f"Updating network outputs to {update_output_names}") - build_args.append(f"--trt-outputs {' '.join(update_output_names)}") - - # Input profiles - if input_profile: - profile_args = defaultdict(str) - for name, dims in input_profile.items(): - assert len(dims) == 3 - profile_args["--trt-min-shapes"] += f"{name}:{str(list(dims[0])).replace(' ', '')} " - profile_args["--trt-opt-shapes"] += f"{name}:{str(list(dims[1])).replace(' ', '')} " - profile_args["--trt-max-shapes"] += f"{name}:{str(list(dims[2])).replace(' ', '')} " - - build_args.extend(f"{k} {v}" for k, v in profile_args.items()) - - # Filter out empty strings and join command - build_args = [arg for arg in build_args if arg] - final_command = ' '.join(build_command + build_args) - - # Execute command with improved error handling - try: - print(f"Engine build command: {final_command}") - subprocess.run(final_command, check=True, shell=True) - except subprocess.CalledProcessError as exc: - error_msg = ( - f"Failed to build TensorRT engine. Error details:\n" - f"Command: {exc.cmd}\n" - ) - raise RuntimeError(error_msg) from exc - - def load(self, weight_streaming=False, weight_streaming_budget_percentage=None): - if self.engine is not None: - print(f"[W]: Engine {self.engine_path} already loaded, skip reloading") - return - if not hasattr(self, "engine_bytes_cpu") or self.engine_bytes_cpu is None: - # keep a cpu copy of the engine to reduce reloading time. - print(f"Loading TensorRT engine to cpu bytes: {self.engine_path}") - self.engine_bytes_cpu = bytes_from_path(self.engine_path) - print(f"Loading TensorRT engine from bytes: {self.engine_path}") - self.engine = engine_from_bytes(self.engine_bytes_cpu) - if weight_streaming: - if weight_streaming_budget_percentage is None: - warnings.warn( - f"Weight streaming budget is not set for {self.engine_path}. Weights will not be streamed." - ) - else: - self.engine.weight_streaming_budget_v2 = int( - weight_streaming_budget_percentage / 100 * self.engine.streamable_weights_size - ) - - def unload(self, verbose=True): - if self.engine is not None: - if verbose: - print(f"Unloading TensorRT engine: {self.engine_path}") - del self.engine - self.engine = None - gc.collect() - else: - if verbose: - print(f"[W]: Unload an unloaded engine {self.engine_path}, skip unloading") - - def activate(self, device_memory=None): - if device_memory is not None: - self.context = self.engine.create_execution_context( - trt.ExecutionContextAllocationStrategy.USER_MANAGED - ) - self.context.device_memory = device_memory - else: - self.context = self.engine.create_execution_context() - - def reactivate(self, device_memory): - assert self.context - self.context.device_memory = device_memory - - def deactivate(self): - del self.context - self.context = None - - def allocate_buffers(self, shape_dict=None, device="cuda"): - for binding in range(self.engine.num_io_tensors): - name = self.engine.get_tensor_name(binding) - if shape_dict and name in shape_dict: - shape = shape_dict[name] - else: - shape = self.engine.get_tensor_shape(name) - print( - f"[W]: {self.engine_path}: Could not find '{name}' in shape dict {shape_dict}. Using shape {shape} inferred from the engine." - ) - if self.engine.get_tensor_mode(name) == trt.TensorIOMode.INPUT: - self.context.set_input_shape(name, shape) - dtype = trt_to_torch_dtype_dict[self.engine.get_tensor_dtype(name)] - tensor = torch.empty(tuple(shape), dtype=dtype).to(device=device) - self.tensors[name] = tensor - - def deallocate_buffers(self): - if not self.engine: - return - for idx in range(self.engine.num_io_tensors): - binding = self.engine[idx] - del self.tensors[binding] - - def infer(self, feed_dict, stream, use_cuda_graph=False): - for name, buf in feed_dict.items(): - self.tensors[name].copy_(buf) - - for name, tensor in self.tensors.items(): - self.context.set_tensor_address(name, tensor.data_ptr()) - - if use_cuda_graph: - if self.cuda_graph_instance is not None: - _CUASSERT(cudart.cudaGraphLaunch(self.cuda_graph_instance, stream)) - _CUASSERT(cudart.cudaStreamSynchronize(stream)) - else: - # do inference before CUDA graph capture - noerror = self.context.execute_async_v3(stream) - if not noerror: - raise ValueError(f"ERROR: inference of {self.engine_path} failed.") - # capture cuda graph - _CUASSERT( - cudart.cudaStreamBeginCapture(stream, cudart.cudaStreamCaptureMode.cudaStreamCaptureModeGlobal) - ) - self.context.execute_async_v3(stream) - self.graph = _CUASSERT(cudart.cudaStreamEndCapture(stream)) - self.cuda_graph_instance = _CUASSERT(cudart.cudaGraphInstantiate(self.graph, 0)) - else: - noerror = self.context.execute_async_v3(stream) - if not noerror: - raise ValueError(f"ERROR: inference of {self.engine_path} failed.") - - return self.tensors diff --git a/demo/Diffusion/demo_diffusion/image/__init__.py b/demo/Diffusion/demo_diffusion/image/__init__.py deleted file mode 100644 index f0c165e09..000000000 --- a/demo/Diffusion/demo_diffusion/image/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from demo_diffusion.image.load import ( - download_image, - prepare_mask_and_masked_image, - preprocess_image, - save_image, -) -from demo_diffusion.image.resize import resize_with_antialiasing -from demo_diffusion.image.video import tensor2vid - -__all__ = [ - "preprocess_image", - "prepare_mask_and_masked_image", - "download_image", - "save_image", - "resize_with_antialiasing", - "tensor2vid", -] diff --git a/demo/Diffusion/demo_diffusion/image/load.py b/demo/Diffusion/demo_diffusion/image/load.py deleted file mode 100644 index 6b198a76f..000000000 --- a/demo/Diffusion/demo_diffusion/image/load.py +++ /dev/null @@ -1,78 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import os -import random -from io import BytesIO - -import numpy as np -import requests -import torch -from PIL import Image - - -def preprocess_image(image): - """ - image: torch.Tensor - """ - w, h = image.size - w, h = map(lambda x: x - x % 32, (w, h)) # resize to integer multiple of 32 - image = image.resize((w, h)) - image = np.array(image).astype(np.float32) / 255.0 - image = image[None].transpose(0, 3, 1, 2) - image = torch.from_numpy(image).contiguous() - return 2.0 * image - 1.0 - - -def prepare_mask_and_masked_image(image, mask): - """ - image: PIL.Image.Image - mask: PIL.Image.Image - """ - if isinstance(image, Image.Image): - image = np.array(image.convert("RGB")) - image = image[None].transpose(0, 3, 1, 2) - image = torch.from_numpy(image).to(dtype=torch.float32).contiguous() / 127.5 - 1.0 - if isinstance(mask, Image.Image): - mask = np.array(mask.convert("L")) - mask = mask.astype(np.float32) / 255.0 - mask = mask[None, None] - mask[mask < 0.5] = 0 - mask[mask >= 0.5] = 1 - mask = torch.from_numpy(mask).to(dtype=torch.float32).contiguous() - - masked_image = image * (mask < 0.5) - - return mask, masked_image - - -def download_image(url): - response = requests.get(url) - return Image.open(BytesIO(response.content)).convert("RGB") - - -def save_image(images, image_path_dir, image_name_prefix, image_name_suffix): - """ - Save the generated images to png files. - """ - for i in range(images.shape[0]): - image_path = os.path.join( - image_path_dir, - f"{image_name_prefix}{i + 1}-{random.randint(1000, 9999)}-{image_name_suffix}.png", - ) - print(f"Saving image {i+1} / {images.shape[0]} to: {image_path}") - Image.fromarray(images[i]).save(image_path) diff --git a/demo/Diffusion/demo_diffusion/image/resize.py b/demo/Diffusion/demo_diffusion/image/resize.py deleted file mode 100644 index c9e8cfc54..000000000 --- a/demo/Diffusion/demo_diffusion/image/resize.py +++ /dev/null @@ -1,123 +0,0 @@ -# Copyright 2024 The HuggingFace Team. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import torch - - -# Taken from https://github.com/huggingface/diffusers/blob/be62c85cd973f2001ab8c5d8919a9a6811fc7e43/src/diffusers/pipelines/stable_video_diffusion/pipeline_stable_video_diffusion.py#L633 -def resize_with_antialiasing(input, size, interpolation="bicubic", align_corners=True): - h, w = input.shape[-2:] - factors = (h / size[0], w / size[1]) - - # First, we have to determine sigma - # Taken from skimage: https://github.com/scikit-image/scikit-image/blob/v0.19.2/skimage/transform/_warps.py#L171 - sigmas = ( - max((factors[0] - 1.0) / 2.0, 0.001), - max((factors[1] - 1.0) / 2.0, 0.001), - ) - - # Now kernel size. Good results are for 3 sigma, but that is kind of slow. Pillow uses 1 sigma - # https://github.com/python-pillow/Pillow/blob/master/src/libImaging/Resample.c#L206 - # But they do it in the 2 passes, which gives better results. Let's try 2 sigmas for now - ks = int(max(2.0 * 2 * sigmas[0], 3)), int(max(2.0 * 2 * sigmas[1], 3)) - - # Make sure it is odd - if (ks[0] % 2) == 0: - ks = ks[0] + 1, ks[1] - - if (ks[1] % 2) == 0: - ks = ks[0], ks[1] + 1 - - input = _gaussian_blur2d(input, ks, sigmas) - - output = torch.nn.functional.interpolate(input, size=size, mode=interpolation, align_corners=align_corners) - return output - - -def _compute_padding(kernel_size): - """Compute padding tuple.""" - # 4 or 6 ints: (padding_left, padding_right,padding_top,padding_bottom) - # https://pytorch.org/docs/stable/nn.html#torch.nn.functional.pad - if len(kernel_size) < 2: - raise AssertionError(kernel_size) - computed = [k - 1 for k in kernel_size] - - # for even kernels we need to do asymmetric padding :( - out_padding = 2 * len(kernel_size) * [0] - - for i in range(len(kernel_size)): - computed_tmp = computed[-(i + 1)] - - pad_front = computed_tmp // 2 - pad_rear = computed_tmp - pad_front - - out_padding[2 * i + 0] = pad_front - out_padding[2 * i + 1] = pad_rear - - return out_padding - - -def _filter2d(input, kernel): - # prepare kernel - b, c, h, w = input.shape - tmp_kernel = kernel[:, None, ...].to(device=input.device, dtype=input.dtype) - - tmp_kernel = tmp_kernel.expand(-1, c, -1, -1) - - height, width = tmp_kernel.shape[-2:] - - padding_shape: list[int] = _compute_padding([height, width]) - input = torch.nn.functional.pad(input, padding_shape, mode="reflect") - - # kernel and input tensor reshape to align element-wise or batch-wise params - tmp_kernel = tmp_kernel.reshape(-1, 1, height, width) - input = input.view(-1, tmp_kernel.size(0), input.size(-2), input.size(-1)) - - # convolve the tensor with the kernel. - output = torch.nn.functional.conv2d(input, tmp_kernel, groups=tmp_kernel.size(0), padding=0, stride=1) - - out = output.view(b, c, h, w) - return out - - -def _gaussian(window_size: int, sigma): - if isinstance(sigma, float): - sigma = torch.tensor([[sigma]]) - - batch_size = sigma.shape[0] - - x = (torch.arange(window_size, device=sigma.device, dtype=sigma.dtype) - window_size // 2).expand(batch_size, -1) - - if window_size % 2 == 0: - x = x + 0.5 - - gauss = torch.exp(-x.pow(2.0) / (2 * sigma.pow(2.0))) - - return gauss / gauss.sum(-1, keepdim=True) - - -def _gaussian_blur2d(input, kernel_size, sigma): - if isinstance(sigma, tuple): - sigma = torch.tensor([sigma], dtype=input.dtype) - else: - sigma = sigma.to(dtype=input.dtype) - - ky, kx = int(kernel_size[0]), int(kernel_size[1]) - bs = sigma.shape[0] - kernel_x = _gaussian(kx, sigma[:, 1].view(bs, 1)) - kernel_y = _gaussian(ky, sigma[:, 0].view(bs, 1)) - out_x = _filter2d(input, kernel_x[..., None, :]) - out = _filter2d(out_x, kernel_y[..., None]) - - return out diff --git a/demo/Diffusion/demo_diffusion/image/video.py b/demo/Diffusion/demo_diffusion/image/video.py deleted file mode 100644 index 825aec840..000000000 --- a/demo/Diffusion/demo_diffusion/image/video.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (c) Alibaba, Inc. and its affiliates. -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import torch - - -# Not a contribution -# Changes made by NVIDIA CORPORATION & AFFILIATES enabling tensor2vid or otherwise documented as -# NVIDIA-proprietary are not a contribution and subject to the terms and conditions at the top of the file -def tensor2vid(video: torch.Tensor, processor, output_type="np"): - # Based on: - # https://github.com/modelscope/modelscope/blob/1509fdb973e5871f37148a4b5e5964cafd43e64d/modelscope/pipelines/multi_modal/text_to_video_synthesis_pipeline.py#L78 - - batch_size, channels, num_frames, height, width = video.shape - outputs = [] - for batch_idx in range(batch_size): - batch_vid = video[batch_idx].permute(1, 0, 2, 3) - batch_output = processor.postprocess(batch_vid, output_type) - - outputs.append(batch_output) - - return outputs diff --git a/demo/Diffusion/demo_diffusion/model/__init__.py b/demo/Diffusion/demo_diffusion/model/__init__.py deleted file mode 100644 index d165b4ed9..000000000 --- a/demo/Diffusion/demo_diffusion/model/__init__.py +++ /dev/null @@ -1,111 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from demo_diffusion.model.base_model import BaseModel -from demo_diffusion.model.clip import ( - CLIPImageProcessorModel, - CLIPModel, - CLIPVisionWithProjModel, - CLIPWithProjModel, - SD3_CLIPGModel, - SD3_CLIPLModel, - SD3_T5XXLModel, - get_clip_embedding_dim, -) -from demo_diffusion.model.controlnet import SD3ControlNet -from demo_diffusion.model.diffusion_transformer import ( - CosmosTransformerModel, - FluxTransformerModel, - SD3_MMDiTModel, - SD3TransformerModel, - WanTransformerModel, -) -from demo_diffusion.model.gan import VQGANModel -from demo_diffusion.model.load import unload_torch_model -from demo_diffusion.model.lora import FLUXLoraLoader, SDLoraLoader, merge_loras -from demo_diffusion.model.scheduler import make_scheduler -from demo_diffusion.model.t5 import T5Model -from demo_diffusion.model.tokenizer import make_tokenizer -from demo_diffusion.model.unet import ( - UNet2DConditionControlNetModel, - UNetCascadeModel, - UNetModel, - UNetTemporalModel, - UNetXLModel, - UNetXLModelControlNet, -) -from demo_diffusion.model.vae import ( - AutoencoderKLWanEncoderModel, - AutoencoderKLWanModel, - SD3_VAEDecoderModel, - SD3_VAEEncoderModel, - TorchVAEEncoder, - VAEDecTemporalModel, - VAEEncoderModel, - VAEModel, -) - -__all__ = [ - # base_model - "BaseModel", - # clip - "get_clip_embedding_dim", - "CLIPModel", - "CLIPWithProjModel", - "SD3_CLIPGModel", - "SD3_CLIPLModel", - "SD3_T5XXLModel", - "CLIPVisionWithProjModel", - "CLIPImageProcessorModel", - "CosmosTransformerModel", - # diffusion_transformer - "SD3_MMDiTModel", - "FluxTransformerModel", - "SD3TransformerModel", - "SD3ControlNet", - "WanTransformerModel", - # gan - "VQGANModel", - # lora - "SDLoraLoader", - "FLUXLoraLoader", - "merge_loras", - # scheduler - "make_scheduler", - # t5 - "T5Model", - # tokenizer - "make_tokenizer", - # unet - "UNetModel", - "UNetXLModel", - "UNetXLModelControlNet", - "UNet2DConditionControlNetModel", - "UNetTemporalModel", - "UNetCascadeModel", - # vae - "VAEModel", - "SD3_VAEDecoderModel", - "VAEDecTemporalModel", - "TorchVAEEncoder", - "VAEEncoderModel", - "SD3_VAEEncoderModel", - "AutoencoderKLWanModel", - "AutoencoderKLWanEncoderModel", - # load - "unload_torch_model", -] diff --git a/demo/Diffusion/demo_diffusion/model/base_model.py b/demo/Diffusion/demo_diffusion/model/base_model.py deleted file mode 100644 index f7e69be53..000000000 --- a/demo/Diffusion/demo_diffusion/model/base_model.py +++ /dev/null @@ -1,320 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import gc -import json -import os - -import numpy as np -import onnx -import torch -from diffusers import DiffusionPipeline -from onnx import numpy_helper - -from demo_diffusion.model import load, optimizer -from demo_diffusion.model.lora import merge_loras - - -class BaseModel: - def __init__( - self, - version="1.4", - pipeline=None, - device="cuda", - hf_token="", - verbose=True, - framework_model_dir="pytorch_model", - fp16=False, - tf32=False, - bf16=False, - int8=False, - fp8=False, - fp4=False, - max_batch_size=16, - text_maxlen=77, - embedding_dim=768, - compression_factor=8, - ): - - self.name = self.__class__.__name__ - self.pipeline_type = pipeline - self.pipeline = pipeline.name - self.version = version - self.path = load.get_path(version, pipeline) - self.device = device - self.hf_token = hf_token - self.hf_safetensor = True - self.verbose = verbose - self.framework_model_dir = framework_model_dir - - self.fp16 = fp16 - self.tf32 = tf32 - self.bf16 = bf16 - self.int8 = int8 - self.fp8 = fp8 - self.fp4 = fp4 - - self.compression_factor = compression_factor - self.min_batch = 1 - self.max_batch = max_batch_size - self.min_image_shape = 256 # min image resolution: 256x256 - self.max_image_shape = 1360 # max image resolution: 1360x1360 - self.min_latent_shape = self.min_image_shape // self.compression_factor - self.max_latent_shape = self.max_image_shape // self.compression_factor - - self.text_maxlen = text_maxlen - self.embedding_dim = embedding_dim - self.extra_output_names = [] - - self.do_constant_folding = True - - def get_pipeline(self): - model_opts = {"variant": "fp16", "torch_dtype": torch.float16} if self.fp16 else {} - model_opts = {"torch_dtype": torch.bfloat16} if self.bf16 else model_opts - return DiffusionPipeline.from_pretrained( - self.path, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - - def get_model(self, torch_inference=""): - pass - - def get_input_names(self): - pass - - def get_output_names(self): - pass - - def get_dynamic_axes(self): - return None - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - pass - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - return None - - def get_shape_dict(self, batch_size, image_height, image_width): - return None - - # Helper utility for ONNX export - def export_onnx( - self, - onnx_path, - onnx_opt_path, - onnx_opset, - opt_image_height, - opt_image_width, - opt_num_frames=None, - custom_model=None, - enable_lora_merge=False, - static_shape=False, - lora_loader=None, - dynamo=False, - ): - onnx_opt_graph = None - # Export optimized ONNX model (if missing) - if not os.path.exists(onnx_opt_path): - if not os.path.exists(onnx_path): - print(f"[I] Exporting ONNX model: {onnx_path}") - - def export_onnx(model): - if enable_lora_merge: - assert lora_loader is not None - model = merge_loras(model, lora_loader) - - export_kwargs = {} - if dynamo: - export_kwargs["dynamic_shapes"] = self.get_dynamic_axes() - else: - export_kwargs["dynamic_axes"] = self.get_dynamic_axes() - - inputs = self.get_sample_input( - 1, opt_image_height, opt_image_width, static_shape, - **({'num_frames': opt_num_frames} if opt_num_frames else {}) - ) - - with torch.no_grad(): - torch.onnx.export( - model, - inputs, - onnx_path, - export_params=True, - do_constant_folding=self.do_constant_folding, - input_names=self.get_input_names(), - output_names=self.get_output_names(), - verbose=False, - dynamo=dynamo, - opset_version=onnx_opset, - **export_kwargs, - ) - - if custom_model: - with torch.inference_mode(): - export_onnx(custom_model) - else: - # WAR: Enable autocast for BF16 Stable Cascade pipeline - do_autocast = True if self.version == "cascade" and self.bf16 else False - model = self.get_model() - with torch.inference_mode(), torch.autocast("cuda", enabled=do_autocast): - export_onnx(model) - del model - gc.collect() - torch.cuda.empty_cache() - else: - print(f"[I] Found cached ONNX model: {onnx_path}") - - print(f"[I] Optimizing ONNX model: {onnx_opt_path}") - onnx_opt_graph = self.optimize(onnx.load(onnx_path)) - if load.onnx_graph_needs_external_data(onnx_opt_graph): - onnx.save_model( - onnx_opt_graph, - onnx_opt_path, - save_as_external_data=True, - all_tensors_to_one_file=True, - convert_attribute=False, - ) - else: - onnx.save(onnx_opt_graph, onnx_opt_path) - else: - print(f"[I] Found cached optimized ONNX model: {onnx_opt_path} ") - - # Helper utility for weights map - def export_weights_map(self, onnx_opt_path, weights_map_path): - if not os.path.exists(weights_map_path): - onnx_opt_dir = os.path.dirname(onnx_opt_path) - onnx_opt_model = onnx.load(onnx_opt_path) - state_dict = self.get_model().state_dict() - # Create initializer data hashes - initializer_hash_mapping = {} - for initializer in onnx_opt_model.graph.initializer: - initializer_data = numpy_helper.to_array(initializer, base_dir=onnx_opt_dir).astype(np.float16) - initializer_hash = hash(initializer_data.data.tobytes()) - initializer_hash_mapping[initializer.name] = (initializer_hash, initializer_data.shape) - - weights_name_mapping = {} - weights_shape_mapping = {} - # set to keep track of initializers already added to the name_mapping dict - initializers_mapped = set() - for wt_name, wt in state_dict.items(): - # get weight hash - wt = wt.cpu().detach().numpy().astype(np.float16) - wt_hash = hash(wt.data.tobytes()) - wt_t_hash = hash(np.transpose(wt).data.tobytes()) - - for initializer_name, (initializer_hash, initializer_shape) in initializer_hash_mapping.items(): - # Due to constant folding, some weights are transposed during export - # To account for the transpose op, we compare the initializer hash to the - # hash for the weight and its transpose - if wt_hash == initializer_hash or wt_t_hash == initializer_hash: - # The assert below ensures there is a 1:1 mapping between - # PyTorch and ONNX weight names. It can be removed in cases where 1:many - # mapping is found and name_mapping[wt_name] = list() - assert initializer_name not in initializers_mapped - weights_name_mapping[wt_name] = initializer_name - initializers_mapped.add(initializer_name) - is_transpose = False if wt_hash == initializer_hash else True - weights_shape_mapping[wt_name] = (initializer_shape, is_transpose) - - # Sanity check: Were any weights not matched - if wt_name not in weights_name_mapping: - print(f"[I] PyTorch weight {wt_name} not matched with any ONNX initializer") - print(f"[I] {len(weights_name_mapping.keys())} PyTorch weights were matched with ONNX initializers") - assert weights_name_mapping.keys() == weights_shape_mapping.keys() - with open(weights_map_path, "w") as fp: - json.dump([weights_name_mapping, weights_shape_mapping], fp) - else: - print(f"[I] Found cached weights map: {weights_map_path} ") - - def optimize(self, onnx_graph, return_onnx=True, **kwargs): - opt = optimizer.Optimizer(onnx_graph, verbose=self.verbose, version=self.version) - opt.info(self.name + ": original") - opt.cleanup() - opt.info(self.name + ": cleanup") - if kwargs.get("modify_fp8_graph", False): - is_fp16_io = kwargs.get("is_fp16_io", True) - opt.modify_fp8_graph(is_fp16_io=is_fp16_io) - opt.info(self.name + ": modify fp8 graph") - elif self.bf16: - # Cast Resize I/O for strongly-typed TRT builds: BF16 -> FP32 inputs, FP32 -> BF16 outputs. - # TRT does not support BF16 for the Resize operator. - opt.infer_shapes() - opt.cast_resize_io(output_dtype=onnx.TensorProto.BFLOAT16) - opt.info(self.name + ": cast resize I/O for bf16") - if self.version.startswith("flux.1") and self.fp8: - opt.flux_convert_rope_weight_type() - opt.info(self.name + ": convert rope weight type for fp8 flux") - opt.fold_constants() - opt.info(self.name + ": fold constants") - opt.infer_shapes() - opt.info(self.name + ": shape inference") - if kwargs.get("modify_int8_graph", False): - opt.modify_int8_graph() - opt.info(self.name + ": modify int8 graph") - onnx_opt_graph = opt.cleanup(return_onnx=return_onnx) - opt.info(self.name + ": finished") - return onnx_opt_graph - - def check_dims(self, batch_size, image_height, image_width, num_frames=None): - assert batch_size >= self.min_batch and batch_size <= self.max_batch - latent_height = image_height // self.compression_factor - latent_width = image_width // self.compression_factor - assert latent_height >= self.min_latent_shape and latent_height <= self.max_latent_shape - assert latent_width >= self.min_latent_shape and latent_width <= self.max_latent_shape - - if num_frames: - latent_frames = (self.num_frames - 1) // self.temporal_compression_factor + 1 - return (latent_height, latent_width, latent_frames) - - return (latent_height, latent_width) - - def get_minmax_dims(self, batch_size, image_height, image_width, static_batch, static_shape, num_frames=None): - min_batch = batch_size if static_batch else self.min_batch - max_batch = batch_size if static_batch else self.max_batch - latent_height = image_height // self.compression_factor - latent_width = image_width // self.compression_factor - min_image_height = image_height if static_shape else self.min_image_shape - max_image_height = image_height if static_shape else self.max_image_shape - min_image_width = image_width if static_shape else self.min_image_shape - max_image_width = image_width if static_shape else self.max_image_shape - min_latent_height = latent_height if static_shape else self.min_latent_shape - max_latent_height = latent_height if static_shape else self.max_latent_shape - min_latent_width = latent_width if static_shape else self.min_latent_shape - max_latent_width = latent_width if static_shape else self.max_latent_shape - - frame_dims = () - if num_frames: - latent_frames = (num_frames - 1) // self.temporal_compression_factor + 1 - min_latent_frames = latent_frames if static_shape else self.min_latent_frames - max_latent_frames = latent_frames if static_shape else self.max_latent_frames - frame_dims = (min_latent_frames, max_latent_frames) - - return ( - min_batch, - max_batch, - min_image_height, - max_image_height, - min_image_width, - max_image_width, - min_latent_height, - max_latent_height, - min_latent_width, - max_latent_width, - *frame_dims - ) diff --git a/demo/Diffusion/demo_diffusion/model/clip.py b/demo/Diffusion/demo_diffusion/model/clip.py deleted file mode 100644 index 37d434b3f..000000000 --- a/demo/Diffusion/demo_diffusion/model/clip.py +++ /dev/null @@ -1,555 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import os - -import torch -from huggingface_hub import hf_hub_download -from safetensors import safe_open -from transformers import ( - CLIPImageProcessor, - CLIPTextModel, - CLIPTextModelWithProjection, - CLIPVisionModelWithProjection, -) - -from demo_diffusion.model import base_model, load, optimizer -from demo_diffusion.utils_sd3.other_impls import ( - SDClipModel, - SDXLClipG, - T5XXLModel, - load_into, -) - - -def get_clipwithproj_embedding_dim(version: str, subfolder: str) -> int: - """Return the embedding dimension of a CLIP with projection model.""" - if version in ("xl-1.0", "xl-turbo", "cascade"): - return 1280 - elif version in {"3.5-medium", "3.5-large"} and subfolder == "text_encoder": - return 768 - elif version in {"3.5-medium", "3.5-large"} and subfolder == "text_encoder_2": - return 1280 - else: - raise ValueError(f"Invalid version {version} + subfolder {subfolder}") - - -def get_clip_embedding_dim(version, pipeline): - if version in ( - "1.4", - "dreamshaper-7", - "flux.1-dev", - "flux.1-schnell", - "flux.1-dev-canny", - "flux.1-dev-depth", - "flux.1-kontext-dev", - ): - return 768 - elif version in ("xl-1.0", "xl-turbo") and pipeline.is_sd_xl_base(): - return 768 - elif version in ("sd3"): - return 4096 - else: - raise ValueError(f"Invalid version {version} + pipeline {pipeline}") - - -class CLIPModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - max_batch_size, - embedding_dim, - fp16=False, - tf32=False, - bf16=False, - output_hidden_states=False, - keep_pooled_output=False, - subfolder="text_encoder", - ): - super(CLIPModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - tf32=tf32, - bf16=bf16, - max_batch_size=max_batch_size, - embedding_dim=embedding_dim, - ) - self.subfolder = subfolder - self.hidden_layer_offset = 0 if pipeline.is_cascade() else -1 - self.keep_pooled_output = keep_pooled_output - - # Output the final hidden state - if output_hidden_states: - self.extra_output_names = ["hidden_states"] - - def get_model(self, torch_inference=""): - model_opts = ( - {"torch_dtype": torch.float16} if self.fp16 else {"torch_dtype": torch.bfloat16} if self.bf16 else {} - ) - clip_model_dir = load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, self.subfolder) - if not load.is_model_cached(clip_model_dir, model_opts, self.hf_safetensor, model_name="model"): - model = CLIPTextModel.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - attn_implementation="eager", - **model_opts, - ).to(self.device) - model.save_pretrained(clip_model_dir, **model_opts) - else: - print(f"[I] Load CLIPTextModel model from: {clip_model_dir}") - model = CLIPTextModel.from_pretrained(clip_model_dir, **model_opts).to(self.device) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return ["input_ids"] - - def get_output_names(self): - output_names = ["text_embeddings"] - if self.keep_pooled_output: - output_names += ["pooled_embeddings"] - return output_names - - def get_dynamic_axes(self): - dynamic_axes = { - "input_ids": {0: "B"}, - "text_embeddings": {0: "B"}, - } - if self.keep_pooled_output: - dynamic_axes["pooled_embeddings"] = {0: "B"} - return dynamic_axes - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - self.check_dims(batch_size, image_height, image_width) - min_batch, max_batch, _, _, _, _, _, _, _, _ = self.get_minmax_dims( - batch_size, image_height, image_width, static_batch, static_shape - ) - return { - "input_ids": [(min_batch, self.text_maxlen), (batch_size, self.text_maxlen), (max_batch, self.text_maxlen)] - } - - def get_shape_dict(self, batch_size, image_height, image_width): - self.check_dims(batch_size, image_height, image_width) - output = { - "input_ids": (batch_size, self.text_maxlen), - "text_embeddings": (batch_size, self.text_maxlen, self.embedding_dim), - } - if self.keep_pooled_output: - output["pooled_embeddings"] = (batch_size, self.embedding_dim) - if "hidden_states" in self.extra_output_names: - output["hidden_states"] = (batch_size, self.text_maxlen, self.embedding_dim) - return output - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - self.check_dims(batch_size, image_height, image_width) - return torch.zeros(batch_size, self.text_maxlen, dtype=torch.int32, device=self.device) - - def optimize(self, onnx_graph): - opt = optimizer.Optimizer(onnx_graph, verbose=self.verbose, version=self.version) - opt.info(self.name + ": original") - keep_outputs = [0, 1] if self.keep_pooled_output else [0] - opt.select_outputs(keep_outputs) - opt.cleanup() - opt.fold_constants() - opt.info(self.name + ": fold constants") - opt.infer_shapes() - opt.info(self.name + ": shape inference") - opt.select_outputs(keep_outputs, names=self.get_output_names()) # rename network outputs - opt.info(self.name + ": rename network output(s)") - opt_onnx_graph = opt.cleanup(return_onnx=True) - if "hidden_states" in self.extra_output_names: - opt_onnx_graph = opt.clip_add_hidden_states(self.hidden_layer_offset, return_onnx=True) - opt.info(self.name + ": added hidden_states") - opt.info(self.name + ": finished") - return opt_onnx_graph - -class CLIPWithProjModel(CLIPModel): - - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - bf16=False, - max_batch_size=16, - output_hidden_states=False, - subfolder="text_encoder_2", - ): - - super(CLIPWithProjModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - bf16=bf16, - max_batch_size=max_batch_size, - embedding_dim=get_clipwithproj_embedding_dim(version, subfolder), - output_hidden_states=output_hidden_states, - ) - self.subfolder = subfolder - - def get_model(self, torch_inference=""): - model_opts = {"variant": "fp16", "torch_dtype": torch.float16} if self.fp16 else {"torch_dtype": torch.bfloat16} - clip_model_dir = load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, self.subfolder) - if not load.is_model_cached(clip_model_dir, model_opts, self.hf_safetensor, model_name="model"): - model = CLIPTextModelWithProjection.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - attn_implementation="eager", - **model_opts, - ).to(self.device) - model.save_pretrained(clip_model_dir, **model_opts) - else: - print(f"[I] Load CLIPTextModelWithProjection model from: {clip_model_dir}") - model = CLIPTextModelWithProjection.from_pretrained(clip_model_dir, **model_opts).to(self.device) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return ["input_ids", "attention_mask"] - - def get_output_names(self): - return ["text_embeddings"] - - def get_dynamic_axes(self): - return { - "input_ids": {0: "B"}, - "attention_mask": {0: "B"}, - "text_embeddings": {0: "B"}, - } - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - self.check_dims(batch_size, image_height, image_width) - min_batch, max_batch, _, _, _, _, _, _, _, _ = self.get_minmax_dims( - batch_size, image_height, image_width, static_batch, static_shape - ) - return { - "input_ids": [(min_batch, self.text_maxlen), (batch_size, self.text_maxlen), (max_batch, self.text_maxlen)], - "attention_mask": [ - (min_batch, self.text_maxlen), - (batch_size, self.text_maxlen), - (max_batch, self.text_maxlen), - ], - } - - def get_shape_dict(self, batch_size, image_height, image_width): - self.check_dims(batch_size, image_height, image_width) - output = { - "input_ids": (batch_size, self.text_maxlen), - "attention_mask": (batch_size, self.text_maxlen), - "text_embeddings": (batch_size, self.embedding_dim), - } - if "hidden_states" in self.extra_output_names: - output["hidden_states"] = (batch_size, self.text_maxlen, self.embedding_dim) - return output - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - self.check_dims(batch_size, image_height, image_width) - return ( - torch.zeros(batch_size, self.text_maxlen, dtype=torch.int32, device=self.device), - torch.zeros(batch_size, self.text_maxlen, dtype=torch.int32, device=self.device), - ) - -class SD3_CLIPGModel(CLIPModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - max_batch_size, - embedding_dim=None, - fp16=False, - pooled_output=False, - ): - self.CLIPG_CONFIG = { - "hidden_act": "gelu", - "hidden_size": 1280, - "intermediate_size": 5120, - "num_attention_heads": 20, - "num_hidden_layers": 32, - } - super(SD3_CLIPGModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - max_batch_size=max_batch_size, - embedding_dim=self.CLIPG_CONFIG["hidden_size"] if embedding_dim is None else embedding_dim, - ) - self.subfolder = "text_encoders" - if pooled_output: - self.extra_output_names = ["pooled_output"] - - def get_model(self, torch_inference=""): - clip_g_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - clip_g_filename = "clip_g.safetensors" - clip_g_model_path = f"{clip_g_model_dir}/{clip_g_filename}" - if not os.path.exists(clip_g_model_path): - hf_hub_download( - repo_id=self.path, - filename=clip_g_filename, - local_dir=load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, ""), - subfolder=self.subfolder, - ) - with safe_open(clip_g_model_path, framework="pt", device=self.device) as f: - dtype = torch.float16 if self.fp16 else torch.float32 - model = SDXLClipG(self.CLIPG_CONFIG, device=self.device, dtype=dtype) - load_into(f, model.transformer, "", self.device, dtype) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_shape_dict(self, batch_size, image_height, image_width): - self.check_dims(batch_size, image_height, image_width) - output = { - "input_ids": (batch_size, self.text_maxlen), - "text_embeddings": (batch_size, self.text_maxlen, self.embedding_dim), - } - if "pooled_output" in self.extra_output_names: - output["pooled_output"] = (batch_size, self.embedding_dim) - - return output - - def optimize(self, onnx_graph): - opt = optimizer.Optimizer(onnx_graph, verbose=self.verbose, version=self.version) - opt.info(self.name + ": original") - opt.select_outputs([0, 1]) - opt.cleanup() - opt.fold_constants() - opt.info(self.name + ": fold constants") - opt.infer_shapes() - opt.info(self.name + ": shape inference") - opt.select_outputs([0, 1], names=["text_embeddings", "pooled_output"]) # rename network output - opt.info(self.name + ": rename output[0] and output[1]") - opt_onnx_graph = opt.cleanup(return_onnx=True) - opt.info(self.name + ": finished") - return opt_onnx_graph - - -class SD3_CLIPLModel(SD3_CLIPGModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - max_batch_size, - fp16=False, - pooled_output=False, - ): - self.CLIPL_CONFIG = { - "hidden_act": "quick_gelu", - "hidden_size": 768, - "intermediate_size": 3072, - "num_attention_heads": 12, - "num_hidden_layers": 12, - } - super(SD3_CLIPLModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - max_batch_size=max_batch_size, - embedding_dim=self.CLIPL_CONFIG["hidden_size"], - ) - self.subfolder = "text_encoders" - if pooled_output: - self.extra_output_names = ["pooled_output"] - - def get_model(self, torch_inference=""): - clip_l_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - clip_l_filename = "clip_l.safetensors" - clip_l_model_path = f"{clip_l_model_dir}/{clip_l_filename}" - if not os.path.exists(clip_l_model_path): - hf_hub_download( - repo_id=self.path, - filename=clip_l_filename, - local_dir=load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, ""), - subfolder=self.subfolder, - ) - with safe_open(clip_l_model_path, framework="pt", device=self.device) as f: - dtype = torch.float16 if self.fp16 else torch.float32 - model = SDClipModel( - layer="hidden", - layer_idx=-2, - device=self.device, - dtype=dtype, - layer_norm_hidden_state=False, - return_projected_pooled=False, - textmodel_json_config=self.CLIPL_CONFIG, - ) - load_into(f, model.transformer, "", self.device, dtype) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - -# NOTE: For legacy reasons, even though this is a T5 model, it inherits from CLIPModel. -class SD3_T5XXLModel(CLIPModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - max_batch_size, - embedding_dim, - fp16=False, - ): - super(SD3_T5XXLModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - max_batch_size=max_batch_size, - embedding_dim=embedding_dim, - ) - self.T5_CONFIG = {"d_ff": 10240, "d_model": 4096, "num_heads": 64, "num_layers": 24, "vocab_size": 32128} - self.subfolder = "text_encoders" - - def get_model(self, torch_inference=""): - t5xxl_model_dir = load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, self.subfolder) - t5xxl_filename = "t5xxl_fp16.safetensors" - t5xxl_model_path = f"{t5xxl_model_dir}/{t5xxl_filename}" - if not os.path.exists(t5xxl_model_path): - hf_hub_download( - repo_id=self.path, - filename=t5xxl_filename, - local_dir=load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, ""), - subfolder=self.subfolder, - ) - with safe_open(t5xxl_model_path, framework="pt", device=self.device) as f: - dtype = torch.float16 if self.fp16 else torch.float32 - model = T5XXLModel(self.T5_CONFIG, device=self.device, dtype=dtype) - load_into(f, model.transformer, "", self.device, dtype) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - -class CLIPVisionWithProjModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - max_batch_size=1, - subfolder="image_encoder", - ): - - super(CLIPVisionWithProjModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - max_batch_size=max_batch_size, - ) - self.subfolder = subfolder - - def get_model(self, torch_inference=""): - clip_model_dir = load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, self.subfolder) - if not os.path.exists(clip_model_dir): - model = CLIPVisionModelWithProjection.from_pretrained( - self.path, subfolder=self.subfolder, use_safetensors=self.hf_safetensor, token=self.hf_token - ).to(self.device) - model.save_pretrained(clip_model_dir) - else: - print(f"[I] Load CLIPVisionModelWithProjection model from: {clip_model_dir}") - model = CLIPVisionModelWithProjection.from_pretrained(clip_model_dir).to(self.device) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - -class CLIPImageProcessorModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - max_batch_size=1, - subfolder="feature_extractor", - ): - - super(CLIPImageProcessorModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - max_batch_size=max_batch_size, - ) - self.subfolder = subfolder - - def get_model(self, torch_inference=""): - clip_model_dir = load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, self.subfolder) - # NOTE to(device) not supported - if not os.path.exists(clip_model_dir): - model = CLIPImageProcessor.from_pretrained( - self.path, subfolder=self.subfolder, use_safetensors=self.hf_safetensor, token=self.hf_token - ) - model.save_pretrained(clip_model_dir) - else: - print(f"[I] Load CLIPImageProcessor model from: {clip_model_dir}") - model = CLIPImageProcessor.from_pretrained(clip_model_dir) - return model diff --git a/demo/Diffusion/demo_diffusion/model/controlnet.py b/demo/Diffusion/demo_diffusion/model/controlnet.py deleted file mode 100644 index 5eb569133..000000000 --- a/demo/Diffusion/demo_diffusion/model/controlnet.py +++ /dev/null @@ -1,223 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - - -import os - -import torch - -from demo_diffusion.dynamic_import import import_from_diffusers -from demo_diffusion.model import base_model, load, optimizer - -# List of models to import from diffusers.models -models_to_import = ["SD3Transformer2DModel", "SD3ControlNetModel"] -for model in models_to_import: - globals()[model] = import_from_diffusers(model, "diffusers.models") - - -class SD3ControlNetWrapper(torch.nn.Module): - def __init__(self, controlnet): - super().__init__() - self.controlnet = controlnet - - def forward(self, hidden_states, controlnet_cond, conditioning_scale, pooled_projections, timestep): - params = { - "hidden_states": hidden_states, - "pooled_projections": pooled_projections, - "timestep": timestep, - "controlnet_cond": controlnet_cond, - "conditioning_scale": conditioning_scale, - } - out = self.controlnet(**params)["controlnet_block_samples"] - return torch.stack(out, dim=0) - - -class SD3ControlNet(base_model.BaseModel): - - def __init__( - self, - version, - controlnet, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - tf32=False, - bf16=False, - int8=False, - fp8=False, - max_batch_size=16, - do_classifier_free_guidance=False, - ): - super(SD3ControlNet, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - tf32=tf32, - bf16=bf16, - int8=int8, - fp8=fp8, - max_batch_size=max_batch_size, - ) - self.path = load.get_path(version, pipeline, controlnet) - self.subfolder = "controlnet_{}".format(controlnet) - self.controlnet_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - self.transformer_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, "transformer" - ) - if not os.path.exists(self.controlnet_model_dir): - self.config = SD3ControlNetModel.load_config(self.path, token=self.hf_token) - else: - print(f"[I] Load SD3ControlNetModel config from: {self.controlnet_model_dir}") - self.config = SD3ControlNetModel.load_config(self.controlnet_model_dir) - self.xB = 2 if do_classifier_free_guidance else 1 # batch multiplier - - def get_model(self, torch_inference=""): - model_opts = ( - {"torch_dtype": torch.float16} if self.fp16 else {"torch_dtype": torch.bfloat16} if self.bf16 else {} - ) - if not load.is_model_cached(self.controlnet_model_dir, model_opts, self.hf_safetensor): - model = SD3ControlNetModel.from_pretrained(self.path, **model_opts, use_safetensors=self.hf_safetensor).to( - self.device - ) - model.save_pretrained(self.controlnet_model_dir, **model_opts) - else: - print(f"[I] Load SD3ControlNetModel model from: {self.controlnet_model_dir}") - model = SD3ControlNetModel.from_pretrained(self.controlnet_model_dir, **model_opts).to(self.device) - - # Load transformer model for pos_embed - transformer = SD3Transformer2DModel.from_pretrained(self.transformer_model_dir, **model_opts).to(self.device) - - if hasattr(model.config, "use_pos_embed") and model.config.use_pos_embed is False: - pos_embed = model._get_pos_embed_from_transformer(transformer) - model.pos_embed = pos_embed.to(model.dtype).to(model.device) - # Free transformer model - del transformer - - model = optimizer.optimize_checkpoint(model, torch_inference) - model = SD3ControlNetWrapper(model) - return model - - def get_input_names(self): - return ["hidden_states", "controlnet_cond", "conditioning_scale", "pooled_projections", "timestep"] - - def get_output_names(self): - return ["controlnet_block_samples"] - - def get_dynamic_axes(self): - xB = "2B" if self.xB == 2 else "B" - dynamic_axes = { - "hidden_states": {0: xB, 2: "H", 3: "W"}, - "controlnet_cond": {0: xB, 2: "H", 3: "W"}, - "pooled_projections": {0: xB}, - "timestep": {0: xB}, - } - return dynamic_axes - - def get_input_profile( - self, - batch_size: int, - image_height: int, - image_width: int, - static_batch: bool, - static_shape: bool, - ): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - ( - min_batch, - max_batch, - _, - _, - _, - _, - min_latent_height, - max_latent_height, - min_latent_width, - max_latent_width, - ) = self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - - input_profile = { - "hidden_states": [ - (self.xB * min_batch, self.config["in_channels"], min_latent_height, min_latent_width), - (self.xB * batch_size, self.config["in_channels"], latent_height, latent_width), - (self.xB * max_batch, self.config["in_channels"], max_latent_height, max_latent_width), - ], - "timestep": [(self.xB * min_batch,), (self.xB * batch_size,), (self.xB * max_batch,)], - "pooled_projections": [ - (self.xB * min_batch, self.config["pooled_projection_dim"]), - (self.xB * batch_size, self.config["pooled_projection_dim"]), - (self.xB * max_batch, self.config["pooled_projection_dim"]), - ], - "controlnet_cond": [ - (self.xB * min_batch, self.config["in_channels"], min_latent_height, min_latent_width), - (self.xB * batch_size, self.config["in_channels"], latent_height, latent_width), - (self.xB * max_batch, self.config["in_channels"], max_latent_height, max_latent_width), - ], - } - return input_profile - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - shape_dict = { - "hidden_states": (self.xB * batch_size, self.config["in_channels"], latent_height, latent_width), - "timestep": (self.xB * batch_size,), - "pooled_projections": (self.xB * batch_size, self.config["pooled_projection_dim"]), - "controlnet_cond": (self.xB * batch_size, self.config["in_channels"], latent_height, latent_width), - "conditioning_scale": (), - "controlnet_block_samples": ( - self.config["num_layers"], - self.xB * batch_size, - latent_height // 2 * latent_width // 2, - self.config["num_attention_heads"] * self.config["attention_head_dim"], - ), - } - return shape_dict - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - dtype = torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32 - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - sample_input = ( - torch.randn( - self.xB * batch_size, - self.config["in_channels"], - latent_height, - latent_width, - dtype=dtype, - device=self.device, - ), - torch.randn( - self.xB * batch_size, - self.config["in_channels"], - latent_height, - latent_width, - dtype=dtype, - device=self.device, - ), - torch.tensor(1.0, dtype=dtype, device=self.device), - torch.randn(self.xB * batch_size, self.config["pooled_projection_dim"], dtype=dtype, device=self.device), - torch.randn(self.xB * batch_size, dtype=torch.float32, device=self.device), - ) - - return sample_input diff --git a/demo/Diffusion/demo_diffusion/model/diffusion_transformer.py b/demo/Diffusion/demo_diffusion/model/diffusion_transformer.py deleted file mode 100644 index 255c51f80..000000000 --- a/demo/Diffusion/demo_diffusion/model/diffusion_transformer.py +++ /dev/null @@ -1,1013 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import os - -import torch -from huggingface_hub import hf_hub_download -from safetensors import safe_open - -from demo_diffusion.dynamic_import import import_from_diffusers -from demo_diffusion.model import base_model, load, optimizer -from demo_diffusion.utils_sd3.other_impls import load_into -from demo_diffusion.utils_sd3.sd3_impls import BaseModel as BaseModelSD3 - -# List of models to import from diffusers.models -models_to_import = ["FluxTransformer2DModel", "SD3Transformer2DModel", "WanTransformer3DModel", "CosmosTransformer3DModel"] -for model in models_to_import: - globals()[model] = import_from_diffusers(model, "diffusers.models") - -# Import FluxKontextUtil from pipeline module -# Using a deferred import to avoid circular dependencies -def _get_flux_kontext_util(): - from demo_diffusion.pipeline.flux_pipeline import FluxKontextUtil - return FluxKontextUtil - -class SD3_MMDiTModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - shift=1.0, - fp16=False, - max_batch_size=16, - text_maxlen=77, - ): - - super(SD3_MMDiTModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - max_batch_size=max_batch_size, - text_maxlen=text_maxlen, - ) - self.subfolder = "sd3" - self.mmdit_dim = 16 - self.shift = shift - self.xB = 2 - - def get_model(self, torch_inference=""): - sd3_model_dir = load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, self.subfolder) - sd3_filename = "sd3_medium.safetensors" - sd3_model_path = f"{sd3_model_dir}/{sd3_filename}" - if not os.path.exists(sd3_model_path): - hf_hub_download(repo_id=self.path, filename=sd3_filename, local_dir=sd3_model_dir) - with safe_open(sd3_model_path, framework="pt", device=self.device) as f: - model = BaseModelSD3( - shift=self.shift, file=f, prefix="model.diffusion_model.", device=self.device, dtype=torch.float16 - ).eval() - load_into(f, model, "model.", self.device, torch.float16) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return ["sample", "sigma", "c_crossattn", "y"] - - def get_output_names(self): - return ["latent"] - - def get_dynamic_axes(self): - xB = "2B" if self.xB == 2 else "B" - return { - "sample": {0: xB, 2: "H", 3: "W"}, - "sigma": {0: xB}, - "c_crossattn": {0: xB}, - "y": {0: xB}, - "latent": {0: xB, 2: "H", 3: "W"}, - } - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - min_batch, max_batch, _, _, _, _, min_latent_height, max_latent_height, min_latent_width, max_latent_width = ( - self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - ) - return { - "sample": [ - (self.xB * min_batch, self.mmdit_dim, min_latent_height, min_latent_width), - (self.xB * batch_size, self.mmdit_dim, latent_height, latent_width), - (self.xB * max_batch, self.mmdit_dim, max_latent_height, max_latent_width), - ], - "sigma": [(self.xB * min_batch,), (self.xB * batch_size,), (self.xB * max_batch,)], - "c_crossattn": [ - (self.xB * min_batch, 154, 4096), - (self.xB * batch_size, 154, 4096), - (self.xB * max_batch, 154, 4096), - ], - "y": [(self.xB * min_batch, 2048), (self.xB * batch_size, 2048), (self.xB * max_batch, 2048)], - } - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - return { - "sample": (self.xB * batch_size, self.mmdit_dim, latent_height, latent_width), - "sigma": (self.xB * batch_size,), - "c_crossattn": (self.xB * batch_size, 154, 4096), - "y": (self.xB * batch_size, 2048), - "latent": (self.xB * batch_size, self.mmdit_dim, latent_height, latent_width), - } - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - dtype = torch.float16 if self.fp16 else torch.float32 - return ( - torch.randn(batch_size, self.mmdit_dim, latent_height, latent_width, dtype=dtype, device=self.device), - torch.randn(batch_size, dtype=dtype, device=self.device), - { - "c_crossattn": torch.randn(batch_size, 154, 4096, dtype=dtype, device=self.device), - "y": torch.randn(batch_size, 2048, dtype=dtype, device=self.device), - }, - ) - - -class FluxTransformerModel(base_model.BaseModel): - - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - tf32=False, - int8=False, - fp8=False, - bf16=False, - max_batch_size=16, - text_maxlen=77, - weight_streaming=False, - weight_streaming_budget_percentage=None, - kontext_resolution=None, - ): - super(FluxTransformerModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - tf32=tf32, - int8=int8, - fp8=fp8, - bf16=bf16, - max_batch_size=max_batch_size, - text_maxlen=text_maxlen, - ) - self.subfolder = "transformer" - self.transformer_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - if not os.path.exists(self.transformer_model_dir): - self.config = FluxTransformer2DModel.load_config(self.path, subfolder=self.subfolder, token=self.hf_token) - else: - print(f"[I] Load FluxTransformer2DModel config from: {self.transformer_model_dir}") - self.config = FluxTransformer2DModel.load_config(self.transformer_model_dir) - self.weight_streaming = weight_streaming - self.weight_streaming_budget_percentage = weight_streaming_budget_percentage - self.out_channels = self.config.get("out_channels") or self.config["in_channels"] - self.kontext_resolution = kontext_resolution - - def get_model(self, torch_inference=""): - model_opts = ( - {"torch_dtype": torch.float16} if self.fp16 else {"torch_dtype": torch.bfloat16} if self.bf16 else {} - ) - if not load.is_model_cached(self.transformer_model_dir, model_opts, self.hf_safetensor): - model = FluxTransformer2DModel.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - model.save_pretrained(self.transformer_model_dir, **model_opts) - else: - print(f"[I] Load FluxTransformer2DModel model from: {self.transformer_model_dir}") - model = FluxTransformer2DModel.from_pretrained(self.transformer_model_dir, **model_opts).to(self.device) - if torch_inference: - model.to(memory_format=torch.channels_last) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return [ - "hidden_states", - "encoder_hidden_states", - "pooled_projections", - "timestep", - "img_ids", - "txt_ids", - "guidance", - ] - - def get_output_names(self): - return ["latent"] - - def get_dynamic_axes(self): - dynamic_axes = { - "hidden_states": {0: "B", 1: "latent_dim"}, - "encoder_hidden_states": {0: "B"}, - "pooled_projections": {0: "B"}, - "timestep": {0: "B"}, - "img_ids": {0: "latent_dim"}, - "txt_ids": {}, - } - if self.config["guidance_embeds"]: - dynamic_axes["guidance"] = {0: "B"} - - return dynamic_axes - - def get_context_latent_dim(self, static_shape=False): - FluxKontextUtil = _get_flux_kontext_util() - return FluxKontextUtil.get_context_latent_dim( - version=self.version, - kontext_resolution=self.kontext_resolution, - compression_factor=self.compression_factor, - static_shape=static_shape, - ) - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - ( - min_batch, - max_batch, - min_image_height, - max_image_height, - min_image_width, - max_image_width, - min_latent_height, - max_latent_height, - min_latent_width, - max_latent_width, - ) = self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - - min_context_latent_dim, context_latent_dim, max_context_latent_dim = self.get_context_latent_dim(static_shape) - - input_profile = { - "hidden_states": [ - ( - min_batch, - (min_latent_height // 2) * (min_latent_width // 2) + min_context_latent_dim, - self.config["in_channels"], - ), - ( - batch_size, - (latent_height // 2) * (latent_width // 2) + context_latent_dim, - self.config["in_channels"], - ), - ( - max_batch, - (max_latent_height // 2) * (max_latent_width // 2) + max_context_latent_dim, - self.config["in_channels"], - ), - ], - "encoder_hidden_states": [ - (min_batch, self.text_maxlen, self.config["joint_attention_dim"]), - (batch_size, self.text_maxlen, self.config["joint_attention_dim"]), - (max_batch, self.text_maxlen, self.config["joint_attention_dim"]), - ], - "pooled_projections": [ - (min_batch, self.config["pooled_projection_dim"]), - (batch_size, self.config["pooled_projection_dim"]), - (max_batch, self.config["pooled_projection_dim"]), - ], - "timestep": [(min_batch,), (batch_size,), (max_batch,)], - "img_ids": [ - ((min_latent_height // 2) * (min_latent_width // 2) + min_context_latent_dim, 3), - ((latent_height // 2) * (latent_width // 2) + context_latent_dim, 3), - ((max_latent_height // 2) * (max_latent_width // 2) + max_context_latent_dim, 3), - ], - "txt_ids": [(self.text_maxlen, 3), (self.text_maxlen, 3), (self.text_maxlen, 3)], - } - if self.config["guidance_embeds"]: - input_profile["guidance"] = [(min_batch,), (batch_size,), (max_batch,)] - return input_profile - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - _, context_latent_dim, _ = self.get_context_latent_dim() - shape_dict = { - "hidden_states": ( - batch_size, - (latent_height // 2) * (latent_width // 2) + context_latent_dim, - self.config["in_channels"], - ), - "encoder_hidden_states": (batch_size, self.text_maxlen, self.config["joint_attention_dim"]), - "pooled_projections": (batch_size, self.config["pooled_projection_dim"]), - "timestep": (batch_size,), - "img_ids": ((latent_height // 2) * (latent_width // 2) + context_latent_dim, 3), - "txt_ids": (self.text_maxlen, 3), - "latent": (batch_size, (latent_height // 2) * (latent_width // 2) + context_latent_dim, self.out_channels), - } - if self.config["guidance_embeds"]: - shape_dict["guidance"] = (batch_size,) - return shape_dict - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - dtype = torch.float32 - assert not (self.fp16 and self.bf16), "fp16 and bf16 cannot be enabled simultaneously" - tensor_dtype = torch.bfloat16 if self.bf16 else (torch.float16 if self.fp16 else torch.float32) - - sample_input = ( - torch.randn( - batch_size, - (latent_height // 2) * (latent_width // 2), - self.config["in_channels"], - dtype=tensor_dtype, - device=self.device, - ), - torch.randn( - batch_size, self.text_maxlen, self.config["joint_attention_dim"], dtype=tensor_dtype, device=self.device - ), - torch.randn(batch_size, self.config["pooled_projection_dim"], dtype=tensor_dtype, device=self.device), - torch.tensor([1.0] * batch_size, dtype=tensor_dtype, device=self.device), - torch.randn((latent_height // 2) * (latent_width // 2), 3, dtype=dtype, device=self.device), - torch.randn(self.text_maxlen, 3, dtype=dtype, device=self.device), - {}, - ) - if self.config["guidance_embeds"]: - sample_input[-1]["guidance"] = torch.tensor([1.0] * batch_size, dtype=dtype, device=self.device) - return sample_input - - def optimize(self, onnx_graph): - if self.fp8: - return super().optimize(onnx_graph) - if self.int8: - return super().optimize(onnx_graph, modify_int8_graph=True) - return super().optimize(onnx_graph) - - -class UpcastLayer(torch.nn.Module): - def __init__(self, base_layer: torch.nn.Module, upcast_to: torch.dtype): - super().__init__() - self.output_dtype = next(base_layer.parameters()).dtype - self.upcast_to = upcast_to - self.context_pre_only = base_layer.context_pre_only - - base_layer = base_layer.to(dtype=self.upcast_to) - self.base_layer = base_layer - - def forward(self, *inputs, **kwargs): - casted_inputs = tuple( - in_val.to(self.upcast_to) if isinstance(in_val, torch.Tensor) else in_val for in_val in inputs - ) - - kwarg_casted = {} - for name, val in kwargs.items(): - kwarg_casted[name] = val.to(dtype=self.upcast_to) if isinstance(val, torch.Tensor) else val - - output = self.base_layer(*casted_inputs, **kwarg_casted) - if isinstance(output, tuple): - output = tuple(out.to(self.output_dtype) if isinstance(out, torch.Tensor) else out for out in output) - else: - output = output.to(dtype=self.output_dtype) - return output - - -class SD3TransformerModel(base_model.BaseModel): - - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - tf32=False, - bf16=False, - fp8=False, - int8=False, - fp4=False, - max_batch_size=16, - text_maxlen=256, - weight_streaming=False, - weight_streaming_budget_percentage=None, - do_classifier_free_guidance=False, - ): - super(SD3TransformerModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - tf32=tf32, - bf16=bf16, - fp8=fp8, - int8=int8, - fp4=fp4, - max_batch_size=max_batch_size, - text_maxlen=text_maxlen, - ) - self.subfolder = "transformer" - self.transformer_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - if not os.path.exists(self.transformer_model_dir): - self.config = SD3Transformer2DModel.load_config(self.path, subfolder=self.subfolder, token=self.hf_token) - else: - print(f"[I] Load SD3Transformer2DModel config from: {self.transformer_model_dir}") - self.config = SD3Transformer2DModel.load_config(self.transformer_model_dir) - self.weight_streaming = weight_streaming - self.weight_streaming_budget_percentage = weight_streaming_budget_percentage - self.out_channels = self.config.get("out_channels") - self.xB = 2 if do_classifier_free_guidance else 1 # batch multiplier - self.num_controlnet_layers = 19 # Can be queried from the ControlNet model config - - def get_model(self, torch_inference=""): - model_opts = ( - {"torch_dtype": torch.float16} if self.fp16 else {"torch_dtype": torch.bfloat16} if self.bf16 else {} - ) - if not load.is_model_cached(self.transformer_model_dir, model_opts, self.hf_safetensor): - model = SD3Transformer2DModel.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - model.save_pretrained(self.transformer_model_dir, **model_opts) - else: - print(f"[I] Load SD3Transformer2DModel model from: {self.transformer_model_dir}") - model = SD3Transformer2DModel.from_pretrained(self.transformer_model_dir, **model_opts).to(self.device) - - if self.version == "3.5-large": - model.transformer_blocks[35] = UpcastLayer(model.transformer_blocks[35], torch.float32) - - if torch_inference: - model.to(memory_format=torch.channels_last) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - input_names = [ - "hidden_states", - "encoder_hidden_states", - "pooled_projections", - "timestep", - "block_controlnet_hidden_states" - ] - return input_names - - def get_output_names(self): - return ["latent"] - - def get_dynamic_axes(self): - xB = "2B" if self.xB == 2 else "B" - dynamic_axes = { - "hidden_states": {0: xB, 2: "H", 3: "W"}, - "encoder_hidden_states": {0: xB}, - "pooled_projections": {0: xB}, - "timestep": {0: xB}, - "latent": {0: xB, 2: "H", 3: "W"}, - "block_controlnet_hidden_states": {1: xB, 2: "latent_dim"} - } - return dynamic_axes - - def get_input_profile( - self, - batch_size: int, - image_height: int, - image_width: int, - static_batch: bool, - static_shape: bool, - ): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - ( - min_batch, - max_batch, - _, - _, - _, - _, - min_latent_height, - max_latent_height, - min_latent_width, - max_latent_width, - ) = self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - - input_profile = { - "hidden_states": [ - (self.xB * min_batch, self.config["in_channels"], min_latent_height, min_latent_width), - (self.xB * batch_size, self.config["in_channels"], latent_height, latent_width), - (self.xB * max_batch, self.config["in_channels"], max_latent_height, max_latent_width), - ], - "encoder_hidden_states": [ - (self.xB * min_batch, self.text_maxlen, self.config["joint_attention_dim"]), - (self.xB * batch_size, self.text_maxlen, self.config["joint_attention_dim"]), - (self.xB * max_batch, self.text_maxlen, self.config["joint_attention_dim"]), - ], - "pooled_projections": [ - (self.xB * min_batch, self.config["pooled_projection_dim"]), - (self.xB * batch_size, self.config["pooled_projection_dim"]), - (self.xB * max_batch, self.config["pooled_projection_dim"]), - ], - "timestep": [(self.xB * min_batch,), (self.xB * batch_size,), (self.xB * max_batch,)], - "block_controlnet_hidden_states": [ - ( - self.num_controlnet_layers, - self.xB * min_batch, - min_latent_height // self.config["patch_size"] * min_latent_width // self.config["patch_size"], - self.config["num_attention_heads"] * self.config["attention_head_dim"], - ), - ( - self.num_controlnet_layers, - self.xB * batch_size, - latent_height // self.config["patch_size"] * latent_width // self.config["patch_size"], - self.config["num_attention_heads"] * self.config["attention_head_dim"], - ), - ( - self.num_controlnet_layers, - self.xB * max_batch, - max_latent_height // self.config["patch_size"] * max_latent_width // self.config["patch_size"], - self.config["num_attention_heads"] * self.config["attention_head_dim"], - ), - ] - } - - return input_profile - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - shape_dict = { - "hidden_states": (self.xB * batch_size, self.config["in_channels"], latent_height, latent_width), - "encoder_hidden_states": (self.xB * batch_size, self.text_maxlen, self.config["joint_attention_dim"]), - "pooled_projections": (self.xB * batch_size, self.config["pooled_projection_dim"]), - "timestep": (self.xB * batch_size,), - "latent": (self.xB * batch_size, self.out_channels, latent_height, latent_width), - "block_controlnet_hidden_states": ( - self.num_controlnet_layers, - self.xB * batch_size, - latent_height // self.config["patch_size"] * latent_width // self.config["patch_size"], - self.config["num_attention_heads"] * self.config["attention_head_dim"], - ) - } - return shape_dict - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - assert not (self.fp16 and self.bf16), "fp16 and bf16 cannot be enabled simultaneously" - dtype = torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32 - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - sample_input = ( - torch.randn( - self.xB * batch_size, - self.config["in_channels"], - latent_height, - latent_width, - dtype=dtype, - device=self.device, - ), - torch.randn( - self.xB * batch_size, - self.text_maxlen, - self.config["joint_attention_dim"], - dtype=dtype, - device=self.device, - ), - torch.randn(self.xB * batch_size, self.config["pooled_projection_dim"], dtype=dtype, device=self.device), - torch.randn(self.xB * batch_size, dtype=torch.float32, device=self.device), - { - "block_controlnet_hidden_states": torch.randn( - self.num_controlnet_layers, - self.xB * batch_size, - latent_height // self.config["patch_size"] * latent_width // self.config["patch_size"], - self.config["num_attention_heads"] * self.config["attention_head_dim"], - dtype=dtype, - device=self.device, - ), - } - ) - - return sample_input - - -class WanTransformerModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - subfolder="transformer", - fp16=False, - tf32=False, - bf16=True, - fp8=False, - int8=False, - max_batch_size=1, - text_maxlen=512, - num_frames=81, - height=720, - width=1280, - weight_streaming=False, - weight_streaming_budget_percentage=None, - ): - super(WanTransformerModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - tf32=tf32, - bf16=bf16, - fp8=fp8, - int8=int8, - max_batch_size=max_batch_size, - text_maxlen=text_maxlen, - embedding_dim=4096, - compression_factor=8, - ) - - self.subfolder = subfolder - self.transformer_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - - if not os.path.exists(self.transformer_model_dir): - self.config = WanTransformer3DModel.load_config( - self.path, subfolder=self.subfolder, token=self.hf_token - ) - else: - print(f"[I] Load WanTransformer3DModel config from: {self.transformer_model_dir}") - self.config = WanTransformer3DModel.load_config(self.transformer_model_dir) - - self.weight_streaming = weight_streaming - self.weight_streaming_budget_percentage = weight_streaming_budget_percentage - self.do_constant_folding = False - self.latent_channels = self.config.get("in_channels", 16) - self.temporal_compression_factor = 4 - self.num_frames = num_frames - self.min_latent_frames = 81 # hardcode to 81 frames for Wan 2.2 - self.max_latent_frames = 81 - - def get_model(self, torch_inference=""): - model_opts = {"torch_dtype": torch.bfloat16} if self.bf16 else {} - - if not load.is_model_cached(self.transformer_model_dir, model_opts, self.hf_safetensor): - model = WanTransformer3DModel.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - model.save_pretrained(self.transformer_model_dir, **model_opts) - else: - print(f"[I] Load WanTransformer3DModel model from: {self.transformer_model_dir}") - model = WanTransformer3DModel.from_pretrained(self.transformer_model_dir, **model_opts).to(self.device) - - if torch_inference: - model.to(memory_format=torch.channels_last) - - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return [ - "hidden_states", - "timestep", - "encoder_hidden_states", - ] - - def get_output_names(self): - return ["denoised_latents"] - - def get_dynamic_axes(self): - return {} - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape, num_frames): - latent_height, latent_width, latent_frames = self.check_dims( - batch_size, image_height, image_width, num_frames - ) - - ( - min_batch, - max_batch, - _, - _, - _, - _, - min_latent_height, - max_latent_height, - min_latent_width, - max_latent_width, - min_latent_frames, - max_latent_frames - ) = self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape, num_frames) - - input_profile = { - "hidden_states": [ - (min_batch, self.latent_channels, min_latent_frames, min_latent_height, min_latent_width), - (batch_size, self.latent_channels, latent_frames, latent_height, latent_width), - (max_batch, self.latent_channels, max_latent_frames, max_latent_height, max_latent_width), - ], - "timestep": [ - (min_batch,), - (batch_size,), - (max_batch,) - ], - "encoder_hidden_states": [ - (min_batch, self.text_maxlen, self.embedding_dim), - (batch_size, self.text_maxlen, self.embedding_dim), - (max_batch, self.text_maxlen, self.embedding_dim), - ], - } - - return input_profile - - def get_shape_dict(self, batch_size, image_height, image_width, num_frames): - latent_height, latent_width, latent_frames = self.check_dims( - batch_size, image_height, image_width, num_frames - ) - return { - "hidden_states": ( - batch_size, - self.latent_channels, - latent_frames, - latent_height, - latent_width - ), - "timestep": (batch_size,), - "encoder_hidden_states": ( - batch_size, - self.text_maxlen, - self.embedding_dim - ), - "denoised_latents": ( - batch_size, - self.latent_channels, - latent_frames, - latent_height, - latent_width - ), - } - - def get_sample_input(self, batch_size, image_height, image_width, static_shape, num_frames): - latent_height, latent_width, latent_frames = self.check_dims( - batch_size, image_height, image_width, num_frames - ) - - assert (self.bf16), "transformer must be BF16" - dtype = torch.bfloat16 if self.bf16 else torch.float32 - - timesteps = torch.tensor([999], dtype=torch.long, device=self.device) if self.subfolder == "transformer" else torch.tensor([1], dtype=torch.long, device=self.device) - - sample_input = ( - torch.randn( - batch_size, - self.latent_channels, - latent_frames, - latent_height, - latent_width, - dtype=dtype, - device=self.device, - ), - timesteps, - torch.randn( - batch_size, - self.text_maxlen, - self.embedding_dim, - dtype=dtype, - device=self.device, - ), - ) - - return sample_input - - -class CosmosTransformerModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - tf32=False, - int8=False, - fp8=False, - bf16=False, - max_batch_size=16, - text_maxlen=77, - weight_streaming=False, - weight_streaming_budget_percentage=None, - ): - super(CosmosTransformerModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - tf32=tf32, - int8=int8, - fp8=fp8, - bf16=bf16, - max_batch_size=max_batch_size, - text_maxlen=text_maxlen, - ) - self.subfolder = "transformer" - self.transformer_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - if not os.path.exists(self.transformer_model_dir): - self.config = CosmosTransformer3DModel.load_config(self.path, subfolder=self.subfolder, token=self.hf_token) - else: - print(f"[I] Load CosmosTransformer3DModel config from: {self.transformer_model_dir}") - self.config = CosmosTransformer3DModel.load_config(self.transformer_model_dir) - self.weight_streaming = weight_streaming - self.weight_streaming_budget_percentage = weight_streaming_budget_percentage - - def get_model(self, torch_inference=""): - model_opts = ( - {"torch_dtype": torch.float16} if self.fp16 else {"torch_dtype": torch.bfloat16} if self.bf16 else {} - ) - if not load.is_model_cached(self.transformer_model_dir, model_opts, self.hf_safetensor): - model = CosmosTransformer3DModel.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - model.save_pretrained(self.transformer_model_dir, **model_opts) - else: - print(f"[I] Load CosmosTransformer3DModel model from: {self.transformer_model_dir}") - model = CosmosTransformer3DModel.from_pretrained(self.transformer_model_dir, **model_opts).to(self.device) - if torch_inference: - model.to(memory_format=torch.channels_last) - if self.fp16: - model.transformer_blocks[6].attn1.norm_q.float().to(self.device) - - model = optimizer.optimize_checkpoint(model, torch_inference) - return model.to(self.device) - - def get_input_names(self): - input_names = [ - "hidden_states", - "timestep", - "encoder_hidden_states", - "padding_mask", - ] - if self.pipeline_type.is_video2world(): - input_names.append("fps") - input_names.append("condition_mask") - return input_names - - def get_output_names(self): - return ["latent"] - - def get_dynamic_axes(self): - dynamic_axes = { - "hidden_states": {0: "B", 2: "latent_frames", 3: "latent_H", 4: "latent_W"}, - "timestep": {0: "B"}, - "encoder_hidden_states": {0: "B"}, - "padding_mask": {0: "B", 2: "H", 3: "W"}, - } - if self.pipeline_type.is_video2world(): - dynamic_axes["fps"] = {0: "B"} - dynamic_axes["condition_mask"] = {0: "B", 2: "latent_frames", 3: "latent_H", 4: "latent_W"} - - return dynamic_axes - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - ( - min_batch, - max_batch, - min_image_height, - max_image_height, - min_image_width, - max_image_width, - min_latent_height, - max_latent_height, - min_latent_width, - max_latent_width, - ) = self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - latent_frames = 24 if self.pipeline_type.is_video2world() else 1 - latent_channels = ( - self.config["in_channels"] - 1 if self.pipeline_type.is_video2world() else self.config["in_channels"] - ) - input_profile = { - "hidden_states": [ - (min_batch, latent_channels, latent_frames, min_latent_height, min_latent_width), - (batch_size, latent_channels, latent_frames, latent_height, latent_width), - (max_batch, latent_channels, latent_frames, max_latent_height, max_latent_width), - ], - "timestep": [(min_batch,), (batch_size,), (max_batch,)], - "encoder_hidden_states": [ - (min_batch, self.text_maxlen, self.config["text_embed_dim"]), - (batch_size, self.text_maxlen, self.config["text_embed_dim"]), - (max_batch, self.text_maxlen, self.config["text_embed_dim"]), - ], - "padding_mask": [ - (1, 1, min_image_height, min_image_width), - (1, 1, image_height, image_width), - (1, 1, max_image_height, max_image_width), - ], - } - if self.pipeline_type.is_video2world(): - input_profile["fps"] = [(min_batch,), (batch_size,), (max_batch,)] - input_profile["condition_mask"] = [ - (min_batch, 1, latent_frames, min_latent_height, min_latent_width), - (batch_size, 1, latent_frames, latent_height, latent_width), - (max_batch, 1, latent_frames, max_latent_height, max_latent_width), - ] - return input_profile - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - # TODO: get latent_frames from infer call - latent_frames = 24 if self.pipeline_type.is_video2world() else 1 - latent_channels = ( - self.config["in_channels"] - 1 if self.pipeline_type.is_video2world() else self.config["in_channels"] - ) - shape_dict = { - "hidden_states": (batch_size, latent_channels, latent_frames, latent_height, latent_width), - "timestep": (batch_size,), - "encoder_hidden_states": (batch_size, self.text_maxlen, self.config["text_embed_dim"]), - "padding_mask": (1, 1, image_height, image_width), - "latent": (batch_size, self.config["in_channels"], latent_frames, latent_height, latent_width), - } - - if self.pipeline_type.is_video2world(): - shape_dict["fps"] = (batch_size,) - shape_dict["condition_mask"] = (batch_size, 1, latent_frames, latent_height, latent_width) - return shape_dict - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - dtype = torch.float32 - assert not (self.fp16 and self.bf16), "fp16 and bf16 cannot be enabled simultaneously" - tensor_dtype = torch.bfloat16 if self.bf16 else (torch.float16 if self.fp16 else torch.float32) - latent_frames = 1 - latent_channels = ( - self.config["in_channels"] - 1 if self.pipeline_type.is_video2world() else self.config["in_channels"] - ) - sample_input = ( - { - "hidden_states": torch.randn( - batch_size, - latent_channels, - latent_frames, - latent_height, - latent_width, - dtype=tensor_dtype, - device=self.device, - ), - "timestep": torch.tensor([1.0] * batch_size, dtype=tensor_dtype, device=self.device), - "encoder_hidden_states": torch.randn( - batch_size, self.text_maxlen, self.config["text_embed_dim"], dtype=tensor_dtype, device=self.device - ), - "padding_mask": torch.ones( - batch_size, 1, image_height, image_width, dtype=tensor_dtype, device=self.device - ), - }, - ) - if self.pipeline_type.is_video2world(): - sample_input[-1]["fps"] = torch.tensor([30] * batch_size, dtype=dtype, device=self.device) - sample_input[-1]["condition_mask"] = torch.randn( - batch_size, - 1, - latent_frames, - latent_height, - latent_width, - dtype=tensor_dtype, - device=self.device, - ) - - return sample_input diff --git a/demo/Diffusion/demo_diffusion/model/gan.py b/demo/Diffusion/demo_diffusion/model/gan.py deleted file mode 100644 index bd2c9a385..000000000 --- a/demo/Diffusion/demo_diffusion/model/gan.py +++ /dev/null @@ -1,149 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import torch -from diffusers.pipelines.wuerstchen import PaellaVQModel - -from demo_diffusion.model import base_model, load, optimizer - - -class VQGANModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - bf16=False, - max_batch_size=16, - compression_factor=42, - latent_dim_scale=10.67, - scale_factor=0.3764, - ): - super(VQGANModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - bf16=bf16, - max_batch_size=max_batch_size, - compression_factor=compression_factor, - ) - self.subfolder = "vqgan" - self.latent_dim_scale = latent_dim_scale - self.scale_factor = scale_factor - - def get_model(self, torch_inference=""): - model_opts = {"variant": "bf16", "torch_dtype": torch.bfloat16} if self.bf16 else {} - vqgan_model_dir = load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, self.subfolder) - if not load.is_model_cached(vqgan_model_dir, model_opts, self.hf_safetensor, model_name="model"): - model = PaellaVQModel.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - model.save_pretrained(vqgan_model_dir, **model_opts) - else: - print(f"[I] Load VQGAN pytorch model from: {vqgan_model_dir}") - model = PaellaVQModel.from_pretrained(vqgan_model_dir, **model_opts).to(self.device) - model.forward = model.decode - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return ["latent"] - - def get_output_names(self): - return ["images"] - - def get_dynamic_axes(self): - return {"latent": {0: "B", 2: "H", 3: "W"}, "images": {0: "B", 2: "8H", 3: "8W"}} - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - min_batch, max_batch, _, _, _, _, min_latent_height, max_latent_height, min_latent_width, max_latent_width = ( - self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - ) - return { - "latent": [ - (min_batch, 4, min_latent_height, min_latent_width), - (batch_size, 4, latent_height, latent_width), - (max_batch, 4, max_latent_height, max_latent_width), - ] - } - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - return { - "latent": (batch_size, 4, latent_height, latent_width), - "images": (batch_size, 3, image_height, image_width), - } - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - dtype = torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32 - return torch.randn(batch_size, 4, latent_height, latent_width, dtype=dtype, device=self.device) - - def optimize(self, onnx_graph, return_onnx=True, **kwargs): - onnx_opt_graph = super().optimize(onnx_graph, return_onnx=True, **kwargs) - opt = optimizer.Optimizer(onnx_opt_graph, verbose=self.verbose, version=self.version) - opt.cast_convtranspose_io() - return opt.cleanup(return_onnx=return_onnx) - - def check_dims(self, batch_size, image_height, image_width): - latent_height, latent_width = super().check_dims(batch_size, image_height, image_width) - latent_height = int(latent_height * self.latent_dim_scale) - latent_width = int(latent_width * self.latent_dim_scale) - return (latent_height, latent_width) - - def get_minmax_dims(self, batch_size, image_height, image_width, static_batch, static_shape): - ( - min_batch, - max_batch, - min_image_height, - max_image_height, - min_image_width, - max_image_width, - min_latent_height, - max_latent_height, - min_latent_width, - max_latent_width, - ) = super().get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - min_latent_height = int(min_latent_height * self.latent_dim_scale) - min_latent_width = int(min_latent_width * self.latent_dim_scale) - max_latent_height = int(max_latent_height * self.latent_dim_scale) - max_latent_width = int(max_latent_width * self.latent_dim_scale) - return ( - min_batch, - max_batch, - min_image_height, - max_image_height, - min_image_width, - max_image_width, - min_latent_height, - max_latent_height, - min_latent_width, - max_latent_width, - ) diff --git a/demo/Diffusion/demo_diffusion/model/load.py b/demo/Diffusion/demo_diffusion/model/load.py deleted file mode 100644 index 32849e253..000000000 --- a/demo/Diffusion/demo_diffusion/model/load.py +++ /dev/null @@ -1,119 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -""" -Functions for loading models. -""" -from __future__ import annotations - -import gc -import glob -import os -import sys -from typing import List, Optional - -import torch - -import onnx - - -def onnx_graph_needs_external_data(onnx_graph: onnx.ModelProto) -> bool: - """Return true if ONNX graph needs to store external data.""" - if sys.platform == "win32": - # ByteSize is broken (wraps around) on Windows, so always assume external data is needed. - return True - else: - TWO_GIGABYTES = 2147483648 - return onnx_graph.ByteSize() > TWO_GIGABYTES - - -def get_path(version: str, pipeline: "pipeline.DiffusionPipeline", controlnets: Optional[List[str]] = None) -> str: - """Return the relative path to the model files directory.""" - if controlnets is not None: - if version == "xl-1.0": - return ["diffusers/controlnet-canny-sdxl-1.0"] - if version == "3.5-large": - return f"stabilityai/stable-diffusion-3.5-large-controlnet-{controlnets}" - return ["lllyasviel/sd-controlnet-" + modality for modality in controlnets] - - elif version == "1.4": - return "CompVis/stable-diffusion-v1-4" - elif version == "dreamshaper-7": - return "Lykon/dreamshaper-7" - elif version == "xl-1.0" and pipeline.is_sd_xl_base(): - return "stabilityai/stable-diffusion-xl-base-1.0" - elif version == "xl-1.0" and pipeline.is_sd_xl_refiner(): - return "stabilityai/stable-diffusion-xl-refiner-1.0" - # TODO SDXL turbo with refiner - elif version == "xl-turbo" and pipeline.is_sd_xl_base(): - return "stabilityai/sdxl-turbo" - elif version == "sd3": - return "stabilityai/stable-diffusion-3-medium" - elif version == "3.5-medium": - return "stabilityai/stable-diffusion-3.5-medium" - elif version == "3.5-large": - return "stabilityai/stable-diffusion-3.5-large" - elif version == "svd-xt-1.1" and pipeline.is_img2vid(): - return "stabilityai/stable-video-diffusion-img2vid-xt-1-1" - elif version == "cascade": - if pipeline.is_cascade_decoder(): - return "stabilityai/stable-cascade" - else: - return "stabilityai/stable-cascade-prior" - elif version == "flux.1-dev": - return "black-forest-labs/FLUX.1-dev" - elif version == "flux.1-schnell": - return "black-forest-labs/FLUX.1-schnell" - elif version == "flux.1-dev-canny": - return "black-forest-labs/FLUX.1-Canny-dev" - elif version == "flux.1-dev-depth": - return "black-forest-labs/FLUX.1-Depth-dev" - elif version == "flux.1-kontext-dev": - return "black-forest-labs/FLUX.1-Kontext-dev" - elif version == "wan2.2-t2v-a14b": - return "Wan-AI/Wan2.2-T2V-A14B-Diffusers" - elif version == "cosmos-predict2-2b-text2image": - return "nvidia/Cosmos-Predict2-2B-Text2Image" - elif version == "cosmos-predict2-14b-text2image": - return "nvidia/Cosmos-Predict2-14B-Text2Image" - elif version == "cosmos-predict2-2b-video2world": - return "nvidia/Cosmos-Predict2-2B-Video2World" - elif version == "cosmos-predict2-14b-video2world": - return "nvidia/Cosmos-Predict2-14B-Video2World" - else: - raise ValueError(f"Unsupported version {version} + pipeline {pipeline.name}") - - -# FIXME serialization not supported for torch.compile -def get_checkpoint_dir(framework_model_dir: str, version: str, pipeline: str, subfolder: str) -> str: - """Return the path to the torch model checkpoint directory.""" - return os.path.join(framework_model_dir, version, pipeline, subfolder) - - -def is_model_cached(model_dir, model_opts, hf_safetensor, model_name="diffusion_pytorch_model") -> bool: - """Return True if model was cached.""" - variant = "." + model_opts.get("variant") if "variant" in model_opts else "" - suffix = ".safetensors" if hf_safetensor else ".bin" - # WAR with * for larger models that are split into multiple smaller ckpt files - model_file = model_name + variant + "*" + suffix - return bool(glob.glob(os.path.join(model_dir, model_file))) - - -def unload_torch_model(model): - if model: - del model - torch.cuda.empty_cache() - gc.collect() diff --git a/demo/Diffusion/demo_diffusion/model/lora.py b/demo/Diffusion/demo_diffusion/model/lora.py deleted file mode 100644 index 5e5b2081f..000000000 --- a/demo/Diffusion/demo_diffusion/model/lora.py +++ /dev/null @@ -1,56 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from abc import ABC -from diffusers.loaders import StableDiffusionLoraLoaderMixin, FluxLoraLoaderMixin - - -class LoraLoader(ABC): - def __init__(self, paths, weights, scale): - self.paths = paths - self.weights = weights - self.scale = scale - - -class SDLoraLoader(LoraLoader, StableDiffusionLoraLoaderMixin): - def __init__(self, paths, weights, scale): - super().__init__(paths, weights, scale) - - -class FLUXLoraLoader(LoraLoader, FluxLoraLoaderMixin): - def __init__(self, paths, weights, scale): - super().__init__(paths, weights, scale) - - -def merge_loras(model, lora_loader): - paths, weights, scale = lora_loader.paths, lora_loader.weights, lora_loader.scale - for i, path in enumerate(paths): - print(f"[I] Loading LoRA: {path}, weight {weights[i]}") - if isinstance(lora_loader, SDLoraLoader): - state_dict, network_alphas = lora_loader.lora_state_dict(path, unet_config=model.config) - lora_loader.load_lora_into_unet(state_dict, network_alphas=network_alphas, unet=model, adapter_name=path) - elif isinstance(lora_loader, FLUXLoraLoader): - state_dict, network_alphas = lora_loader.lora_state_dict(path, return_alphas=True) - lora_loader.load_lora_into_transformer(state_dict, network_alphas=network_alphas, transformer=model, adapter_name=path) - else: - raise ValueError(f"Unsupported LoRA loader: {lora_loader}") - - model.set_adapters(paths, weights=weights) - # NOTE: fuse_lora an experimental API in Diffusers - model.fuse_lora(adapter_names=paths, lora_scale=scale) - model.unload_lora() - return model diff --git a/demo/Diffusion/demo_diffusion/model/optimizer.py b/demo/Diffusion/demo_diffusion/model/optimizer.py deleted file mode 100644 index 9083a22b1..000000000 --- a/demo/Diffusion/demo_diffusion/model/optimizer.py +++ /dev/null @@ -1,218 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import os -import re -import tempfile - -import onnx -import onnx_graphsurgeon as gs -import torch -from onnx import shape_inference -from polygraphy.backend.onnx.loader import fold_constants - -from demo_diffusion.model import load -from demo_diffusion.utils_modelopt import ( - cast_convtranspose_io, - cast_fp8_mha_io, - cast_layernorm_io, - cast_resize_io, - convert_fp16_io, - convert_zp_fp8, -) - -# FIXME update callsites after serialization support for torch.compile is added -TORCH_INFERENCE_MODELS = ["default", "reduce-overhead", "max-autotune"] - - -def optimize_checkpoint(model, torch_inference: str): - """Optimize a torch model checkpoint using torch.compile.""" - if not torch_inference or torch_inference == "eager": - return model - assert torch_inference in TORCH_INFERENCE_MODELS - return torch.compile(model, mode=torch_inference, dynamic=False, fullgraph=False) - - -class Optimizer: - - def __init__(self, onnx_graph, verbose=False, version=None): - self.graph = gs.import_onnx(onnx_graph) - self.verbose = verbose - self.version = version - - def info(self, prefix): - if self.verbose: - print( - f"{prefix} .. {len(self.graph.nodes)} nodes, {len(self.graph.tensors().keys())} tensors, {len(self.graph.inputs)} inputs, {len(self.graph.outputs)} outputs" - ) - - def cleanup(self, return_onnx=False): - self.graph.cleanup().toposort() - return gs.export_onnx(self.graph) if return_onnx else self.graph - - def select_outputs(self, keep, names=None): - self.graph.outputs = [self.graph.outputs[o] for o in keep] - if names: - for i, name in enumerate(names): - self.graph.outputs[i].name = name - - def fold_constants(self, return_onnx=False): - onnx_graph = fold_constants(gs.export_onnx(self.graph), allow_onnxruntime_shape_inference=True) - self.graph = gs.import_onnx(onnx_graph) - if return_onnx: - return onnx_graph - - def infer_shapes(self, return_onnx=False): - onnx_graph = gs.export_onnx(self.graph) - if load.onnx_graph_needs_external_data(onnx_graph): - temp_dir = tempfile.TemporaryDirectory().name - os.makedirs(temp_dir, exist_ok=True) - onnx_orig_path = os.path.join(temp_dir, "model.onnx") - onnx_inferred_path = os.path.join(temp_dir, "inferred.onnx") - onnx.save_model( - onnx_graph, - onnx_orig_path, - save_as_external_data=True, - all_tensors_to_one_file=True, - convert_attribute=False, - ) - onnx.shape_inference.infer_shapes_path(onnx_orig_path, onnx_inferred_path) - onnx_graph = onnx.load(onnx_inferred_path) - else: - onnx_graph = shape_inference.infer_shapes(onnx_graph) - - self.graph = gs.import_onnx(onnx_graph) - if return_onnx: - return onnx_graph - - def clip_add_hidden_states(self, hidden_layer_offset, return_onnx=False): - hidden_layers = -1 - onnx_graph = gs.export_onnx(self.graph) - for i in range(len(onnx_graph.graph.node)): - for j in range(len(onnx_graph.graph.node[i].output)): - name = onnx_graph.graph.node[i].output[j] - if "layers" in name: - hidden_layers = max(int(name.split(".")[1].split("/")[0]), hidden_layers) - for i in range(len(onnx_graph.graph.node)): - for j in range(len(onnx_graph.graph.node[i].output)): - if onnx_graph.graph.node[i].output[j] == "/text_model/encoder/layers.{}/Add_1_output_0".format( - hidden_layers + hidden_layer_offset - ): - onnx_graph.graph.node[i].output[j] = "hidden_states" - for j in range(len(onnx_graph.graph.node[i].input)): - if onnx_graph.graph.node[i].input[j] == "/text_model/encoder/layers.{}/Add_1_output_0".format( - hidden_layers + hidden_layer_offset - ): - onnx_graph.graph.node[i].input[j] = "hidden_states" - if return_onnx: - return onnx_graph - - def fuse_mha_qkv_int8_sq(self): - tensors = self.graph.tensors() - keys = tensors.keys() - - # mha : fuse QKV QDQ nodes - # mhca : fuse KV QDQ nodes - q_pat = ( - "/down_blocks.\\d+/attentions.\\d+/transformer_blocks" - ".\\d+/attn\\d+/to_q/input_quantizer/DequantizeLinear_output_0" - ) - k_pat = ( - "/down_blocks.\\d+/attentions.\\d+/transformer_blocks" - ".\\d+/attn\\d+/to_k/input_quantizer/DequantizeLinear_output_0" - ) - v_pat = ( - "/down_blocks.\\d+/attentions.\\d+/transformer_blocks" - ".\\d+/attn\\d+/to_v/input_quantizer/DequantizeLinear_output_0" - ) - - qs = list( - sorted( - map( - lambda x: x.group(0), # type: ignore - filter(lambda x: x is not None, [re.match(q_pat, key) for key in keys]), - ) - ) - ) - ks = list( - sorted( - map( - lambda x: x.group(0), # type: ignore - filter(lambda x: x is not None, [re.match(k_pat, key) for key in keys]), - ) - ) - ) - vs = list( - sorted( - map( - lambda x: x.group(0), # type: ignore - filter(lambda x: x is not None, [re.match(v_pat, key) for key in keys]), - ) - ) - ) - - removed = 0 - assert len(qs) == len(ks) == len(vs), "Failed to collect tensors" - for q, k, v in zip(qs, ks, vs): - is_mha = all(["attn1" in tensor for tensor in [q, k, v]]) - is_mhca = all(["attn2" in tensor for tensor in [q, k, v]]) - assert (is_mha or is_mhca) and (not (is_mha and is_mhca)) - - if is_mha: - tensors[k].outputs[0].inputs[0] = tensors[q] - tensors[v].outputs[0].inputs[0] = tensors[q] - del tensors[k] - del tensors[v] - removed += 2 - else: # is_mhca - tensors[k].outputs[0].inputs[0] = tensors[v] - del tensors[k] - removed += 1 - print(f"Removed {removed} QDQ nodes") - return removed # expected 72 for L2.5 - - def modify_int8_graph(self): - # Cast LayerNorm scale/bias from FP16 to FP32 to match INT8 DQ activations. - cast_layernorm_io(self.graph) - # Fuse QKV QDQ nodes for INT8 SmoothQuant. - self.fuse_mha_qkv_int8_sq() - - def cast_convtranspose_io(self): - cast_convtranspose_io(self.graph) - - def cast_resize_io(self, output_dtype): - cast_resize_io(self.graph, output_dtype=output_dtype) - - def modify_fp8_graph(self, is_fp16_io=True): - onnx_graph = gs.export_onnx(self.graph) - # Convert INT8 Zero to FP8. - onnx_graph = convert_zp_fp8(onnx_graph) - - self.graph = gs.import_onnx(onnx_graph) - # Add cast nodes to Resize I/O. - cast_resize_io(self.graph) - # Convert model inputs and outputs to fp16 I/O. - if is_fp16_io: - convert_fp16_io(self.graph) - # Add cast nodes to MHA's BMM1 and BMM2's I/O. - cast_fp8_mha_io(self.graph) - - def flux_convert_rope_weight_type(self): - for node in self.graph.nodes: - if node.op == "Einsum": - print(f"Fixed RoPE (Rotary Position Embedding) weight type: {node.name}") - return gs.export_onnx(self.graph) diff --git a/demo/Diffusion/demo_diffusion/model/scheduler.py b/demo/Diffusion/demo_diffusion/model/scheduler.py deleted file mode 100644 index 908dd2cd1..000000000 --- a/demo/Diffusion/demo_diffusion/model/scheduler.py +++ /dev/null @@ -1,33 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import os - -from demo_diffusion.model import load - - -def make_scheduler(cls, version, pipeline, hf_token, framework_model_dir, subfolder="scheduler"): - scheduler_dir = os.path.join( - framework_model_dir, version, pipeline.name, next(iter({cls.__name__})).lower(), subfolder - ) - if not os.path.exists(scheduler_dir): - scheduler = cls.from_pretrained(load.get_path(version, pipeline), subfolder=subfolder, token=hf_token) - scheduler.save_pretrained(scheduler_dir) - else: - print(f"[I] Load Scheduler {cls.__name__} from: {scheduler_dir}") - scheduler = cls.from_pretrained(scheduler_dir) - return scheduler diff --git a/demo/Diffusion/demo_diffusion/model/t5.py b/demo/Diffusion/demo_diffusion/model/t5.py deleted file mode 100644 index 6fd8c052d..000000000 --- a/demo/Diffusion/demo_diffusion/model/t5.py +++ /dev/null @@ -1,142 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import os - -import torch -from transformers import ( - AutoConfig, - T5EncoderModel, - UMT5EncoderModel, -) - -from demo_diffusion.model import base_model, load, optimizer - - -class T5Model(base_model.BaseModel): - - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - max_batch_size, - fp16=False, - tf32=False, - bf16=False, - subfolder="text_encoder", - text_maxlen=512, - weight_streaming=False, - weight_streaming_budget_percentage=None, - use_attention_mask=False, - ): - super(T5Model, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - tf32=tf32, - bf16=bf16, - max_batch_size=max_batch_size, - text_maxlen=text_maxlen, - ) - self.subfolder = subfolder - self.t5_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - if not os.path.exists(self.t5_model_dir): - self.config = AutoConfig.from_pretrained(self.path, subfolder=self.subfolder, token=self.hf_token) - else: - print(f"[I] Load T5Encoder Config from: {self.t5_model_dir}") - self.config = AutoConfig.from_pretrained(self.t5_model_dir) - self.is_umt5 = getattr(self.config, 'model_type', '') == 'umt5' - self.weight_streaming = weight_streaming - self.weight_streaming_budget_percentage = weight_streaming_budget_percentage - self.use_attention_mask = use_attention_mask - - def get_model(self, torch_inference=""): - model_opts = ( - {"torch_dtype": torch.float16} if self.fp16 else {"torch_dtype": torch.bfloat16} if self.bf16 else {} - ) - EncoderModelClass = UMT5EncoderModel if self.is_umt5 else T5EncoderModel - if not load.is_model_cached(self.t5_model_dir, model_opts, self.hf_safetensor, model_name="model"): - model = EncoderModelClass.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - model.save_pretrained(self.t5_model_dir, **model_opts) - else: - print(f"[I] Load {EncoderModelClass.__name__} model from: {self.t5_model_dir}") - model = EncoderModelClass.from_pretrained(self.t5_model_dir, **model_opts).to(self.device) - - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - if self.use_attention_mask: - return ["input_ids", "attention_mask"] - return ["input_ids"] - - def get_output_names(self): - return ["text_embeddings"] - - def get_dynamic_axes(self): - if self.use_attention_mask: - return {"input_ids": {0: "B"}, "attention_mask": {0: "B"}, "text_embeddings": {0: "B"}} - return {"input_ids": {0: "B"}, "text_embeddings": {0: "B"}} - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - self.check_dims(batch_size, image_height, image_width) - min_batch, max_batch, _, _, _, _, _, _, _, _ = self.get_minmax_dims( - batch_size, image_height, image_width, static_batch, static_shape - ) - profile = { - "input_ids": [(min_batch, self.text_maxlen), (batch_size, self.text_maxlen), (max_batch, self.text_maxlen)] - } - if self.use_attention_mask: - profile["attention_mask"] = [ - (min_batch, self.text_maxlen), - (batch_size, self.text_maxlen), - (max_batch, self.text_maxlen), - ] - return profile - - def get_shape_dict(self, batch_size, image_height, image_width): - self.check_dims(batch_size, image_height, image_width) - output = { - "input_ids": (batch_size, self.text_maxlen), - "text_embeddings": (batch_size, self.text_maxlen, self.config.d_model), - } - if self.use_attention_mask: - output["attention_mask"] = (batch_size, self.text_maxlen) - return output - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - self.check_dims(batch_size, image_height, image_width) - inputs = {"input_ids": torch.zeros(batch_size, self.text_maxlen, dtype=torch.int32, device=self.device)} - if self.use_attention_mask: - inputs["attention_mask"] = torch.ones(batch_size, self.text_maxlen, dtype=torch.int32, device=self.device) - return inputs diff --git a/demo/Diffusion/demo_diffusion/model/tokenizer.py b/demo/Diffusion/demo_diffusion/model/tokenizer.py deleted file mode 100644 index c82989e08..000000000 --- a/demo/Diffusion/demo_diffusion/model/tokenizer.py +++ /dev/null @@ -1,46 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import os - -from transformers import ( - CLIPTokenizer, - T5TokenizerFast, -) - -from demo_diffusion.model import load - - -def make_tokenizer(version, pipeline, hf_token, framework_model_dir, subfolder="tokenizer", tokenizer_type="clip"): - if tokenizer_type == "clip": - tokenizer_class = CLIPTokenizer - elif tokenizer_type == "t5": - tokenizer_class = T5TokenizerFast - else: - raise ValueError( - f"Unsupported tokenizer_type {tokenizer_type}. Only tokenizer_type clip and t5 are currently supported" - ) - tokenizer_model_dir = load.get_checkpoint_dir(framework_model_dir, version, pipeline.name, subfolder) - if not os.path.exists(tokenizer_model_dir): - model = tokenizer_class.from_pretrained( - load.get_path(version, pipeline), subfolder=subfolder, use_safetensors=pipeline.is_sd_xl(), token=hf_token - ) - model.save_pretrained(tokenizer_model_dir) - else: - print(f"[I] Load {tokenizer_class.__name__} model from: {tokenizer_model_dir}") - model = tokenizer_class.from_pretrained(tokenizer_model_dir) - return model diff --git a/demo/Diffusion/demo_diffusion/model/unet.py b/demo/Diffusion/demo_diffusion/model/unet.py deleted file mode 100644 index 47d088273..000000000 --- a/demo/Diffusion/demo_diffusion/model/unet.py +++ /dev/null @@ -1,902 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -""" -Model definitions for UNet models. -""" - -import torch - -from demo_diffusion.dynamic_import import import_from_diffusers -from demo_diffusion.model import base_model, load, optimizer -from diffusers import StableDiffusionXLControlNetPipeline - -# List of models to import from diffusers.models -models_to_import = [ - "ControlNetModel", - "UNet2DConditionModel", - "UNetSpatioTemporalConditionModel", - "StableCascadeUNet", -] -for model in models_to_import: - globals()[model] = import_from_diffusers(model, "diffusers.models") - - -def get_unet_embedding_dim(version, pipeline): - if version in ("1.4", "dreamshaper-7"): - return 768 - elif version in ("xl-1.0", "xl-turbo") and pipeline.is_sd_xl_base(): - return 2048 - elif version in ("cascade"): - return 1280 - elif version in ("xl-1.0", "xl-turbo") and pipeline.is_sd_xl_refiner(): - return 1280 - elif pipeline.is_img2vid(): - return 1024 - else: - raise ValueError(f"Invalid version {version} + pipeline {pipeline}") - - -class UNet2DConditionControlNetModel(torch.nn.Module): - def __init__(self, unet, controlnets) -> None: - super().__init__() - self.unet = unet - self.controlnets = controlnets - - def forward(self, sample, timestep, encoder_hidden_states, images, controlnet_scales, added_cond_kwargs=None): - for i, (image, conditioning_scale, controlnet) in enumerate(zip(images, controlnet_scales, self.controlnets)): - down_samples, mid_sample = controlnet( - sample, - timestep, - encoder_hidden_states=encoder_hidden_states, - controlnet_cond=image, - return_dict=False, - added_cond_kwargs=added_cond_kwargs, - ) - - down_samples = [down_sample * conditioning_scale for down_sample in down_samples] - mid_sample *= conditioning_scale - - # merge samples - if i == 0: - down_block_res_samples, mid_block_res_sample = down_samples, mid_sample - else: - down_block_res_samples = [ - samples_prev + samples_curr - for samples_prev, samples_curr in zip(down_block_res_samples, down_samples) - ] - mid_block_res_sample += mid_sample - - noise_pred = self.unet( - sample, - timestep, - encoder_hidden_states=encoder_hidden_states, - down_block_additional_residuals=down_block_res_samples, - mid_block_additional_residual=mid_block_res_sample, - added_cond_kwargs=added_cond_kwargs, - ) - return noise_pred - - -class UNetModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - int8=False, - fp8=False, - max_batch_size=16, - text_maxlen=77, - controlnets=None, - do_classifier_free_guidance=False, - ): - - super(UNetModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - int8=int8, - fp8=fp8, - max_batch_size=max_batch_size, - text_maxlen=text_maxlen, - embedding_dim=get_unet_embedding_dim(version, pipeline), - ) - self.subfolder = "unet" - self.controlnets = load.get_path(version, pipeline, controlnets) if controlnets else None - self.unet_dim = 4 - self.xB = 2 if do_classifier_free_guidance else 1 # batch multiplier - - def get_model(self, torch_inference=""): - model_opts = {"variant": "fp16", "torch_dtype": torch.float16} if self.fp16 else {} - if self.controlnets: - unet_model = UNet2DConditionModel.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - cnet_model_opts = {"torch_dtype": torch.float16} if self.fp16 else {} - controlnets = torch.nn.ModuleList( - [ControlNetModel.from_pretrained(path, **cnet_model_opts).to(self.device) for path in self.controlnets] - ) - # FIXME - cache UNet2DConditionControlNetModel - model = UNet2DConditionControlNetModel(unet_model, controlnets) - else: - unet_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - if not load.is_model_cached(unet_model_dir, model_opts, self.hf_safetensor): - model = UNet2DConditionModel.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - model.save_pretrained(unet_model_dir, **model_opts) - else: - print(f"[I] Load UNet2DConditionModel model from: {unet_model_dir}") - model = UNet2DConditionModel.from_pretrained(unet_model_dir, **model_opts).to(self.device) - if torch_inference: - model.to(memory_format=torch.channels_last) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - if self.controlnets is None: - return ["sample", "timestep", "encoder_hidden_states"] - else: - return ["sample", "timestep", "encoder_hidden_states", "images", "controlnet_scales"] - - def get_output_names(self): - return ["latent"] - - def get_dynamic_axes(self): - xB = "2B" if self.xB == 2 else "B" - if self.controlnets is None: - return { - "sample": {0: xB, 2: "H", 3: "W"}, - "encoder_hidden_states": {0: xB}, - "latent": {0: xB, 2: "H", 3: "W"}, - } - else: - return { - "sample": {0: xB, 2: "H", 3: "W"}, - "encoder_hidden_states": {0: xB}, - "images": {1: xB, 3: "8H", 4: "8W"}, - "latent": {0: xB, 2: "H", 3: "W"}, - } - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - # WAR to enable inference for H/W that are not multiples of 16 - # If building with Dynamic Shapes: ensure image height and width are not multiples of 16 for ONNX export and TensorRT engine build - if not static_shape: - image_height = image_height - 8 if image_height % 16 == 0 else image_height - image_width = image_width - 8 if image_width % 16 == 0 else image_width - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - ( - min_batch, - max_batch, - min_image_height, - max_image_height, - min_image_width, - max_image_width, - min_latent_height, - max_latent_height, - min_latent_width, - max_latent_width, - ) = self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - if self.controlnets is None: - return { - "sample": [ - (self.xB * min_batch, self.unet_dim, min_latent_height, min_latent_width), - (self.xB * batch_size, self.unet_dim, latent_height, latent_width), - (self.xB * max_batch, self.unet_dim, max_latent_height, max_latent_width), - ], - "encoder_hidden_states": [ - (self.xB * min_batch, self.text_maxlen, self.embedding_dim), - (self.xB * batch_size, self.text_maxlen, self.embedding_dim), - (self.xB * max_batch, self.text_maxlen, self.embedding_dim), - ], - } - else: - return { - "sample": [ - (self.xB * min_batch, self.unet_dim, min_latent_height, min_latent_width), - (self.xB * batch_size, self.unet_dim, latent_height, latent_width), - (self.xB * max_batch, self.unet_dim, max_latent_height, max_latent_width), - ], - "encoder_hidden_states": [ - (self.xB * min_batch, self.text_maxlen, self.embedding_dim), - (self.xB * batch_size, self.text_maxlen, self.embedding_dim), - (self.xB * max_batch, self.text_maxlen, self.embedding_dim), - ], - "images": [ - (len(self.controlnets), self.xB * min_batch, 3, min_image_height, min_image_width), - (len(self.controlnets), self.xB * batch_size, 3, image_height, image_width), - (len(self.controlnets), self.xB * max_batch, 3, max_image_height, max_image_width), - ], - } - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - if self.controlnets is None: - return { - "sample": (self.xB * batch_size, self.unet_dim, latent_height, latent_width), - "encoder_hidden_states": (self.xB * batch_size, self.text_maxlen, self.embedding_dim), - "latent": (self.xB * batch_size, 4, latent_height, latent_width), - } - else: - return { - "sample": (self.xB * batch_size, self.unet_dim, latent_height, latent_width), - "encoder_hidden_states": (self.xB * batch_size, self.text_maxlen, self.embedding_dim), - "images": (len(self.controlnets), self.xB * batch_size, 3, image_height, image_width), - "latent": (self.xB * batch_size, 4, latent_height, latent_width), - } - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - # WAR to enable inference for H/W that are not multiples of 16 - # If building with Dynamic Shapes: ensure image height and width are not multiples of 16 for ONNX export and TensorRT engine build - if not static_shape: - image_height = image_height - 8 if image_height % 16 == 0 else image_height - image_width = image_width - 8 if image_width % 16 == 0 else image_width - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - dtype = torch.float16 if self.fp16 else torch.float32 - if self.controlnets is None: - return ( - torch.randn(batch_size, self.unet_dim, latent_height, latent_width, dtype=dtype, device=self.device), - torch.tensor([1.0], dtype=dtype, device=self.device), - torch.randn(batch_size, self.text_maxlen, self.embedding_dim, dtype=dtype, device=self.device), - ) - else: - return ( - torch.randn(batch_size, self.unet_dim, latent_height, latent_width, dtype=dtype, device=self.device), - torch.tensor(999, dtype=dtype, device=self.device), - torch.randn(batch_size, self.text_maxlen, self.embedding_dim, dtype=dtype, device=self.device), - torch.randn( - len(self.controlnets), batch_size, 3, image_height, image_width, dtype=dtype, device=self.device - ), - torch.randn(len(self.controlnets), dtype=dtype, device=self.device), - ) - - def optimize(self, onnx_graph): - if self.fp8: - return super().optimize(onnx_graph, modify_fp8_graph=True) - if self.int8: - return super().optimize(onnx_graph, modify_int8_graph=True) - return super().optimize(onnx_graph) - - -class UNetXLModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - int8=False, - fp8=False, - max_batch_size=16, - text_maxlen=77, - do_classifier_free_guidance=False, - ): - super(UNetXLModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - int8=int8, - fp8=fp8, - max_batch_size=max_batch_size, - text_maxlen=text_maxlen, - embedding_dim=get_unet_embedding_dim(version, pipeline), - ) - self.subfolder = "unet" - self.unet_dim = 4 - self.time_dim = 5 if pipeline.is_sd_xl_refiner() else 6 - self.xB = 2 if do_classifier_free_guidance else 1 # batch multiplier - - def get_model(self, torch_inference=""): - model_opts = {"variant": "fp16", "torch_dtype": torch.float16} if self.fp16 else {} - unet_model_dir = load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, self.subfolder) - if not load.is_model_cached(unet_model_dir, model_opts, self.hf_safetensor): - model = UNet2DConditionModel.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - # Use default attention processor for ONNX export - if not torch_inference: - model.set_default_attn_processor() - model.save_pretrained(unet_model_dir, **model_opts) - else: - print(f"[I] Load UNet2DConditionModel model from: {unet_model_dir}") - model = UNet2DConditionModel.from_pretrained(unet_model_dir, **model_opts).to(self.device) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return ["sample", "timestep", "encoder_hidden_states", "text_embeds", "time_ids"] - - def get_output_names(self): - return ["latent"] - - def get_dynamic_axes(self): - xB = "2B" if self.xB == 2 else "B" - return { - "sample": {0: xB, 2: "H", 3: "W"}, - "encoder_hidden_states": {0: xB}, - "latent": {0: xB, 2: "H", 3: "W"}, - "text_embeds": {0: xB}, - "time_ids": {0: xB}, - } - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - # WAR to enable inference for H/W that are not multiples of 16 - # If building with Dynamic Shapes: ensure image height and width are not multiples of 16 for ONNX export and TensorRT engine build - if not static_shape: - image_height = image_height - 8 if image_height % 16 == 0 else image_height - image_width = image_width - 8 if image_width % 16 == 0 else image_width - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - min_batch, max_batch, _, _, _, _, min_latent_height, max_latent_height, min_latent_width, max_latent_width = ( - self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - ) - return { - "sample": [ - (self.xB * min_batch, self.unet_dim, min_latent_height, min_latent_width), - (self.xB * batch_size, self.unet_dim, latent_height, latent_width), - (self.xB * max_batch, self.unet_dim, max_latent_height, max_latent_width), - ], - "encoder_hidden_states": [ - (self.xB * min_batch, self.text_maxlen, self.embedding_dim), - (self.xB * batch_size, self.text_maxlen, self.embedding_dim), - (self.xB * max_batch, self.text_maxlen, self.embedding_dim), - ], - "text_embeds": [(self.xB * min_batch, 1280), (self.xB * batch_size, 1280), (self.xB * max_batch, 1280)], - "time_ids": [ - (self.xB * min_batch, self.time_dim), - (self.xB * batch_size, self.time_dim), - (self.xB * max_batch, self.time_dim), - ], - } - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - return { - "sample": (self.xB * batch_size, self.unet_dim, latent_height, latent_width), - "encoder_hidden_states": (self.xB * batch_size, self.text_maxlen, self.embedding_dim), - "latent": (self.xB * batch_size, 4, latent_height, latent_width), - "text_embeds": (self.xB * batch_size, 1280), - "time_ids": (self.xB * batch_size, self.time_dim), - } - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - # WAR to enable inference for H/W that are not multiples of 16 - # If building with Dynamic Shapes: ensure image height and width are not multiples of 16 for ONNX export and TensorRT engine build - if not static_shape: - image_height = image_height - 8 if image_height % 16 == 0 else image_height - image_width = image_width - 8 if image_width % 16 == 0 else image_width - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - dtype = torch.float16 if self.fp16 else torch.float32 - return ( - torch.randn( - self.xB * batch_size, self.unet_dim, latent_height, latent_width, dtype=dtype, device=self.device - ), - torch.tensor([1.0], dtype=dtype, device=self.device), - torch.randn(self.xB * batch_size, self.text_maxlen, self.embedding_dim, dtype=dtype, device=self.device), - { - "added_cond_kwargs": { - "text_embeds": torch.randn(self.xB * batch_size, 1280, dtype=dtype, device=self.device), - "time_ids": torch.randn(self.xB * batch_size, self.time_dim, dtype=dtype, device=self.device), - } - }, - ) - - def optimize(self, onnx_graph): - if self.fp8: - return super().optimize(onnx_graph, modify_fp8_graph=True) - if self.int8: - return super().optimize(onnx_graph, modify_int8_graph=True) - return super().optimize(onnx_graph) - - -class UNetXLModelControlNet(UNetXLModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - int8=False, - fp8=False, - max_batch_size=16, - text_maxlen=77, - controlnets=None, - do_classifier_free_guidance=False, - ): - super().__init__( - version=version, - pipeline=pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - int8=int8, - fp8=fp8, - max_batch_size=max_batch_size, - text_maxlen=text_maxlen, - do_classifier_free_guidance=do_classifier_free_guidance, - ) - self.controlnets = load.get_path(version, pipeline, controlnets) if controlnets else None - - def get_pipeline(self): - cnet_model_opts = {"torch_dtype": torch.float16} if self.fp16 else {} - controlnets = [ - ControlNetModel.from_pretrained(path, **cnet_model_opts).to(self.device) for path in self.controlnets - ] - if self.bf16: - model_opts = {"torch_dtype": torch.bfloat16} - elif self.fp16: - model_opts = {"variant": "fp16", "torch_dtype": torch.float16} - else: - model_opts = {} - pipeline = StableDiffusionXLControlNetPipeline.from_pretrained( - self.path, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - controlnet=controlnets, - **model_opts, - ).to(self.device) - return pipeline - - def get_model(self, torch_inference=""): - model_opts = {"variant": "fp16", "torch_dtype": torch.float16} if self.fp16 else {} - unet_model = UNet2DConditionModel.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - cnet_model_opts = {"torch_dtype": torch.float16} if self.fp16 else {} - controlnets = torch.nn.ModuleList( - [ControlNetModel.from_pretrained(path, **cnet_model_opts).to(self.device) for path in self.controlnets] - ) - # FIXME - cache UNet2DConditionControlNetModel - model = UNet2DConditionControlNetModel(unet_model, controlnets) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return ["sample", "timestep", "encoder_hidden_states", "images", "controlnet_scales", "text_embeds", "time_ids"] - - def get_dynamic_axes(self): - xB = "2B" if self.xB == 2 else "B" - result = super().get_dynamic_axes() - result["images"] = {1: xB, 3: "8H", 4: "8W"} - return result - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - min_batch, max_batch, min_image_height, max_image_height, min_image_width, max_image_width, _, _, _, _ = ( - self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - ) - result = super().get_input_profile(batch_size, image_height, image_width, static_batch, static_shape) - result["images"] = [ - (len(self.controlnets), self.xB * min_batch, 3, min_image_height, min_image_width), - (len(self.controlnets), self.xB * batch_size, 3, image_height, image_width), - (len(self.controlnets), self.xB * max_batch, 3, max_image_height, max_image_width), - ] - return result - - def get_shape_dict(self, batch_size, image_height, image_width): - result = super().get_shape_dict(batch_size, image_height, image_width) - result["images"] = (len(self.controlnets), self.xB * batch_size, 3, image_height, image_width) - return result - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - dtype = torch.float16 if self.fp16 else torch.float32 - result = super().get_sample_input(batch_size, image_height, image_width, static_shape) - result = ( - result[:-1] - + ( - torch.randn( - len(self.controlnets), - self.xB * batch_size, - 3, - image_height, - image_width, - dtype=dtype, - device=self.device, - ), # images - torch.randn(len(self.controlnets), dtype=dtype, device=self.device), # controlnet_scales - ) - + result[-1:] - ) - return result - - -class UNetTemporalModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - fp8=False, - max_batch_size=16, - num_frames=14, - do_classifier_free_guidance=True, - ): - super(UNetTemporalModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - fp8=fp8, - max_batch_size=max_batch_size, - embedding_dim=get_unet_embedding_dim(version, pipeline), - ) - self.subfolder = "unet" - self.unet_dim = 4 - self.num_frames = num_frames - self.out_channels = 4 - self.cross_attention_dim = 1024 - self.xB = 2 if do_classifier_free_guidance else 1 # batch multiplier - - def get_model(self, torch_inference=""): - model_opts = {"torch_dtype": torch.float16} if self.fp16 else {} - unet_model_dir = load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, self.subfolder) - if not load.is_model_cached(unet_model_dir, model_opts, self.hf_safetensor): - model = UNetSpatioTemporalConditionModel.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - model.save_pretrained(unet_model_dir, **model_opts) - else: - print(f"[I] Load UNetSpatioTemporalConditionModel model from: {unet_model_dir}") - model = UNetSpatioTemporalConditionModel.from_pretrained(unet_model_dir, **model_opts).to(self.device) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return ["sample", "timestep", "encoder_hidden_states", "added_time_ids"] - - def get_output_names(self): - return ["latent"] - - def get_dynamic_axes(self): - xB = str(self.xB) + "B" - return { - "sample": {0: xB, 1: "num_frames", 3: "H", 4: "W"}, - "encoder_hidden_states": {0: xB}, - "added_time_ids": {0: xB}, - } - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - ( - min_batch, - max_batch, - min_image_height, - max_image_height, - min_image_width, - max_image_width, - min_latent_height, - max_latent_height, - min_latent_width, - max_latent_width, - ) = self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - return { - "sample": [ - (self.xB * min_batch, self.num_frames, 2 * self.out_channels, min_latent_height, min_latent_width), - (self.xB * batch_size, self.num_frames, 2 * self.out_channels, latent_height, latent_width), - (self.xB * max_batch, self.num_frames, 2 * self.out_channels, max_latent_height, max_latent_width), - ], - "encoder_hidden_states": [ - (self.xB * min_batch, 1, self.cross_attention_dim), - (self.xB * batch_size, 1, self.cross_attention_dim), - (self.xB * max_batch, 1, self.cross_attention_dim), - ], - "added_time_ids": [(self.xB * min_batch, 3), (self.xB * batch_size, 3), (self.xB * max_batch, 3)], - } - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - return { - "sample": (self.xB * batch_size, self.num_frames, 2 * self.out_channels, latent_height, latent_width), - "timestep": (1,), - "encoder_hidden_states": (self.xB * batch_size, 1, self.cross_attention_dim), - "added_time_ids": (self.xB * batch_size, 3), - } - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - # TODO chunk_size if forward_chunking is used - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - - dtype = torch.float16 if self.fp16 else torch.float32 - return ( - torch.randn( - self.xB * batch_size, - self.num_frames, - 2 * self.out_channels, - latent_height, - latent_width, - dtype=dtype, - device=self.device, - ), - torch.tensor([1.0], dtype=torch.float32, device=self.device), - torch.randn(self.xB * batch_size, 1, self.cross_attention_dim, dtype=dtype, device=self.device), - torch.randn(self.xB * batch_size, 3, dtype=dtype, device=self.device), - ) - - def optimize(self, onnx_graph): - return super().optimize(onnx_graph, modify_fp8_graph=self.fp8) - - -class UNetCascadeModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - bf16=False, - max_batch_size=16, - text_maxlen=77, - do_classifier_free_guidance=False, - compression_factor=42, - latent_dim_scale=10.67, - image_embedding_dim=768, - lite=False, - ): - super(UNetCascadeModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - bf16=bf16, - max_batch_size=max_batch_size, - text_maxlen=text_maxlen, - embedding_dim=get_unet_embedding_dim(version, pipeline), - compression_factor=compression_factor, - ) - self.is_prior = True if pipeline.is_cascade_prior() else False - self.subfolder = "prior" if self.is_prior else "decoder" - if lite: - self.subfolder += "_lite" - self.prior_dim = 16 - self.decoder_dim = 4 - self.xB = 2 if do_classifier_free_guidance else 1 # batch multiplier - self.latent_dim_scale = latent_dim_scale - self.min_latent_shape = self.min_image_shape // self.compression_factor - self.max_latent_shape = self.max_image_shape // self.compression_factor - self.do_constant_folding = False - self.image_embedding_dim = image_embedding_dim - - def get_model(self, torch_inference=""): - # FP16 variant doesn't exist - model_opts = {"torch_dtype": torch.float16} if self.fp16 else {} - model_opts = {"variant": "bf16", "torch_dtype": torch.bfloat16} if self.bf16 else model_opts - unet_model_dir = load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, self.subfolder) - if not load.is_model_cached(unet_model_dir, model_opts, self.hf_safetensor): - model = StableCascadeUNet.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - model.save_pretrained(unet_model_dir, **model_opts) - else: - print(f"[I] Load Stable Cascade UNet pytorch model from: {unet_model_dir}") - model = StableCascadeUNet.from_pretrained(unet_model_dir, **model_opts).to(self.device) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - if self.is_prior: - return ["sample", "timestep_ratio", "clip_text_pooled", "clip_text", "clip_img"] - else: - return ["sample", "timestep_ratio", "clip_text_pooled", "effnet"] - - def get_output_names(self): - return ["latent"] - - def get_dynamic_axes(self): - xB = "2B" if self.xB == 2 else "B" - if self.is_prior: - return { - "sample": {0: xB, 2: "H", 3: "W"}, - "timestep_ratio": {0: xB}, - "clip_text_pooled": {0: xB}, - "clip_text": {0: xB}, - "clip_img": {0: xB}, - "latent": {0: xB, 2: "H", 3: "W"}, - } - else: - return { - "sample": {0: xB, 2: "H", 3: "W"}, - "timestep_ratio": {0: xB}, - "clip_text_pooled": {0: xB}, - "effnet": {0: xB, 2: "H_effnet", 3: "W_effnet"}, - "latent": {0: xB, 2: "H", 3: "W"}, - } - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - min_batch, max_batch, _, _, _, _, min_latent_height, max_latent_height, min_latent_width, max_latent_width = ( - self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - ) - if self.is_prior: - return { - "sample": [ - (self.xB * min_batch, self.prior_dim, min_latent_height, min_latent_width), - (self.xB * batch_size, self.prior_dim, latent_height, latent_width), - (self.xB * max_batch, self.prior_dim, max_latent_height, max_latent_width), - ], - "timestep_ratio": [(self.xB * min_batch,), (self.xB * batch_size,), (self.xB * max_batch,)], - "clip_text_pooled": [ - (self.xB * min_batch, 1, self.embedding_dim), - (self.xB * batch_size, 1, self.embedding_dim), - (self.xB * max_batch, 1, self.embedding_dim), - ], - "clip_text": [ - (self.xB * min_batch, self.text_maxlen, self.embedding_dim), - (self.xB * batch_size, self.text_maxlen, self.embedding_dim), - (self.xB * max_batch, self.text_maxlen, self.embedding_dim), - ], - "clip_img": [ - (self.xB * min_batch, 1, self.image_embedding_dim), - (self.xB * batch_size, 1, self.image_embedding_dim), - (self.xB * max_batch, 1, self.image_embedding_dim), - ], - } - else: - return { - "sample": [ - ( - self.xB * min_batch, - self.decoder_dim, - int(min_latent_height * self.latent_dim_scale), - int(min_latent_width * self.latent_dim_scale), - ), - ( - self.xB * batch_size, - self.decoder_dim, - int(latent_height * self.latent_dim_scale), - int(latent_width * self.latent_dim_scale), - ), - ( - self.xB * max_batch, - self.decoder_dim, - int(max_latent_height * self.latent_dim_scale), - int(max_latent_width * self.latent_dim_scale), - ), - ], - "timestep_ratio": [(self.xB * min_batch,), (self.xB * batch_size,), (self.xB * max_batch,)], - "clip_text_pooled": [ - (self.xB * min_batch, 1, self.embedding_dim), - (self.xB * batch_size, 1, self.embedding_dim), - (self.xB * max_batch, 1, self.embedding_dim), - ], - "effnet": [ - (self.xB * min_batch, self.prior_dim, min_latent_height, min_latent_width), - (self.xB * batch_size, self.prior_dim, latent_height, latent_width), - (self.xB * max_batch, self.prior_dim, max_latent_height, max_latent_width), - ], - } - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - if self.is_prior: - return { - "sample": (self.xB * batch_size, self.prior_dim, latent_height, latent_width), - "timestep_ratio": (self.xB * batch_size,), - "clip_text_pooled": (self.xB * batch_size, 1, self.embedding_dim), - "clip_text": (self.xB * batch_size, self.text_maxlen, self.embedding_dim), - "clip_img": (self.xB * batch_size, 1, self.image_embedding_dim), - "latent": (self.xB * batch_size, self.prior_dim, latent_height, latent_width), - } - else: - return { - "sample": ( - self.xB * batch_size, - self.decoder_dim, - int(latent_height * self.latent_dim_scale), - int(latent_width * self.latent_dim_scale), - ), - "timestep_ratio": (self.xB * batch_size,), - "clip_text_pooled": (self.xB * batch_size, 1, self.embedding_dim), - "effnet": (self.xB * batch_size, self.prior_dim, latent_height, latent_width), - "latent": ( - self.xB * batch_size, - self.decoder_dim, - int(latent_height * self.latent_dim_scale), - int(latent_width * self.latent_dim_scale), - ), - } - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - dtype = torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32 - if self.is_prior: - return ( - torch.randn(batch_size, self.prior_dim, latent_height, latent_width, dtype=dtype, device=self.device), - torch.tensor([1.0] * batch_size, dtype=dtype, device=self.device), - torch.randn(batch_size, 1, self.embedding_dim, dtype=dtype, device=self.device), - { - "clip_text": torch.randn( - batch_size, self.text_maxlen, self.embedding_dim, dtype=dtype, device=self.device - ), - "clip_img": torch.randn(batch_size, 1, self.image_embedding_dim, dtype=dtype, device=self.device), - }, - ) - else: - return ( - torch.randn( - batch_size, - self.decoder_dim, - int(latent_height * self.latent_dim_scale), - int(latent_width * self.latent_dim_scale), - dtype=dtype, - device=self.device, - ), - torch.tensor([1.0] * batch_size, dtype=dtype, device=self.device), - torch.randn(batch_size, 1, self.embedding_dim, dtype=dtype, device=self.device), - { - "effnet": torch.randn( - batch_size, self.prior_dim, latent_height, latent_width, dtype=dtype, device=self.device - ), - }, - ) diff --git a/demo/Diffusion/demo_diffusion/model/vae.py b/demo/Diffusion/demo_diffusion/model/vae.py deleted file mode 100644 index 828ae07ae..000000000 --- a/demo/Diffusion/demo_diffusion/model/vae.py +++ /dev/null @@ -1,671 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import os - -import torch -from huggingface_hub import hf_hub_download -from safetensors import safe_open - -from demo_diffusion.dynamic_import import import_from_diffusers -from demo_diffusion.model import base_model, load, optimizer -from demo_diffusion.utils_sd3.other_impls import load_into -from demo_diffusion.utils_sd3.sd3_impls import SDVAE - -# List of models to import from diffusers.models -models_to_import = ["AutoencoderKL", "AutoencoderKLTemporalDecoder", "AutoencoderKLWan"] -for model in models_to_import: - globals()[model] = import_from_diffusers(model, "diffusers.models") - -# Import FluxKontextUtil from pipeline module -# Using a deferred import to avoid circular dependencies -def _get_flux_kontext_util(): - from demo_diffusion.pipeline.flux_pipeline import FluxKontextUtil - return FluxKontextUtil - - -class VAEModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - tf32=False, - bf16=False, - max_batch_size=16, - ): - super(VAEModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - tf32=tf32, - bf16=bf16, - max_batch_size=max_batch_size, - ) - self.do_constant_folding = False - self.subfolder = "vae" - self.vae_decoder_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - if not os.path.exists(self.vae_decoder_model_dir): - self.config = AutoencoderKL.load_config(self.path, subfolder=self.subfolder, token=self.hf_token) - else: - print(f"[I] Load AutoencoderKL (decoder) config from: {self.vae_decoder_model_dir}") - self.config = AutoencoderKL.load_config(self.vae_decoder_model_dir) - - def get_model(self, torch_inference=""): - model_opts = ( - {"torch_dtype": torch.float16} if self.fp16 else {"torch_dtype": torch.bfloat16} if self.bf16 else {} - ) - if not load.is_model_cached(self.vae_decoder_model_dir, model_opts, self.hf_safetensor): - model = AutoencoderKL.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - model.save_pretrained(self.vae_decoder_model_dir, **model_opts) - else: - print(f"[I] Load AutoencoderKL (decoder) model from: {self.vae_decoder_model_dir}") - model = AutoencoderKL.from_pretrained(self.vae_decoder_model_dir, **model_opts).to(self.device) - model.forward = model.decode - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return ["latent"] - - def get_output_names(self): - return ["images"] - - def get_dynamic_axes(self): - return {"latent": {0: "B", 2: "H", 3: "W"}, "images": {0: "B", 2: "8H", 3: "8W"}} - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - min_batch, max_batch, _, _, _, _, min_latent_height, max_latent_height, min_latent_width, max_latent_width = ( - self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - ) - return { - "latent": [ - (min_batch, self.config["latent_channels"], min_latent_height, min_latent_width), - (batch_size, self.config["latent_channels"], latent_height, latent_width), - (max_batch, self.config["latent_channels"], max_latent_height, max_latent_width), - ] - } - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - return { - "latent": (batch_size, self.config["latent_channels"], latent_height, latent_width), - "images": (batch_size, 3, image_height, image_width), - } - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - dtype = torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32 - return torch.randn( - batch_size, self.config["latent_channels"], latent_height, latent_width, dtype=dtype, device=self.device - ) - - -class SD3_VAEDecoderModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - max_batch_size, - fp16=False, - ): - super(SD3_VAEDecoderModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - max_batch_size=max_batch_size, - ) - self.subfolder = "sd3" - - def get_model(self, torch_inference=""): - dtype = torch.float16 if self.fp16 else torch.float32 - sd3_model_dir = load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, self.subfolder) - sd3_filename = "sd3_medium.safetensors" - sd3_model_path = f"{sd3_model_dir}/{sd3_filename}" - if not os.path.exists(sd3_model_path): - hf_hub_download(repo_id=self.path, filename=sd3_filename, local_dir=sd3_model_dir) - with safe_open(sd3_model_path, framework="pt", device=self.device) as f: - model = SDVAE(device=self.device, dtype=dtype).eval().cuda() - prefix = "" - if any(k.startswith("first_stage_model.") for k in f.keys()): - prefix = "first_stage_model." - load_into(f, model, prefix, self.device, dtype) - model.forward = model.decode - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return ["latent"] - - def get_output_names(self): - return ["images"] - - def get_dynamic_axes(self): - return {"latent": {0: "B", 2: "H", 3: "W"}, "images": {0: "B", 2: "8H", 3: "8W"}} - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - min_batch, max_batch, _, _, _, _, min_latent_height, max_latent_height, min_latent_width, max_latent_width = ( - self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - ) - return { - "latent": [ - (min_batch, 16, min_latent_height, min_latent_width), - (batch_size, 16, latent_height, latent_width), - (max_batch, 16, max_latent_height, max_latent_width), - ] - } - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - return { - "latent": (batch_size, 16, latent_height, latent_width), - "images": (batch_size, 3, image_height, image_width), - } - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - dtype = torch.float16 if self.fp16 else torch.float32 - return torch.randn(batch_size, 16, latent_height, latent_width, dtype=dtype, device=self.device) - - -class VAEDecTemporalModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - max_batch_size=16, - decode_chunk_size=14, - ): - super(VAEDecTemporalModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - max_batch_size=max_batch_size, - ) - self.subfolder = "vae" - self.decode_chunk_size = decode_chunk_size - - def get_model(self, torch_inference=""): - vae_decoder_model_path = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - if not os.path.exists(vae_decoder_model_path): - model = AutoencoderKLTemporalDecoder.from_pretrained( - self.path, subfolder=self.subfolder, use_safetensors=self.hf_safetensor, token=self.hf_token - ).to(self.device) - model.save_pretrained(vae_decoder_model_path) - else: - print(f"[I] Load AutoencoderKLTemporalDecoder model from: {vae_decoder_model_path}") - model = AutoencoderKLTemporalDecoder.from_pretrained(vae_decoder_model_path).to(self.device) - model.forward = model.decode - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return ["latent", "num_frames_in"] - - def get_output_names(self): - return ["frames"] - - def get_dynamic_axes(self): - return {"latent": {0: "num_frames_in", 2: "H", 3: "W"}, "frames": {0: "num_frames_in", 2: "8H", 3: "8W"}} - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - assert batch_size == 1 - _, _, _, _, _, _, min_latent_height, max_latent_height, min_latent_width, max_latent_width = ( - self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - ) - return { - "latent": [ - (1, 4, min_latent_height, min_latent_width), - (self.decode_chunk_size, 4, latent_height, latent_width), - (self.decode_chunk_size, 4, max_latent_height, max_latent_width), - ], - "num_frames_in": [(1,), (1,), (1,)], - } - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - assert batch_size == 1 - return { - "latent": (self.decode_chunk_size, 4, latent_height, latent_width), - #'num_frames_in': (1,), - "frames": (self.decode_chunk_size, 3, image_height, image_width), - } - - def get_sample_input(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - assert batch_size == 1 - return ( - torch.randn( - self.decode_chunk_size, 4, latent_height, latent_width, dtype=torch.float32, device=self.device - ), - self.decode_chunk_size, - ) - - -class TorchVAEEncoder(torch.nn.Module): - def __init__( - self, - version, - pipeline, - hf_token, - device, - path, - framework_model_dir, - subfolder, - fp16=False, - bf16=False, - hf_safetensor=False, - ): - super().__init__() - model_opts = {"torch_dtype": torch.float16} if fp16 else {"torch_dtype": torch.bfloat16} if bf16 else {} - vae_encoder_model_dir = load.get_checkpoint_dir(framework_model_dir, version, pipeline, subfolder) - if not load.is_model_cached(vae_encoder_model_dir, model_opts, hf_safetensor): - self.vae_encoder = AutoencoderKL.from_pretrained( - path, subfolder="vae", use_safetensors=hf_safetensor, token=hf_token, **model_opts - ).to(device) - self.vae_encoder.save_pretrained(vae_encoder_model_dir, **model_opts) - else: - print(f"[I] Load AutoencoderKL (encoder) model from: {vae_encoder_model_dir}") - self.vae_encoder = AutoencoderKL.from_pretrained(vae_encoder_model_dir, **model_opts).to(device) - - def forward(self, x): - return self.vae_encoder.encode(x).latent_dist.sample() - - -class VAEEncoderModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - tf32=False, - bf16=False, - max_batch_size=16, - do_classifier_free_guidance=False, - kontext_resolution=None, - ): - super(VAEEncoderModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - tf32=tf32, - bf16=bf16, - max_batch_size=max_batch_size, - ) - self.kontext_resolution = kontext_resolution - self.subfolder = "vae" - self.vae_encoder_model_dir = load.get_checkpoint_dir( - framework_model_dir, version, self.pipeline, self.subfolder - ) - if not os.path.exists(self.vae_encoder_model_dir): - self.config = AutoencoderKL.load_config(self.path, subfolder=self.subfolder, token=self.hf_token) - else: - print(f"[I] Load AutoencoderKL (encoder) config from: {self.vae_encoder_model_dir}") - self.config = AutoencoderKL.load_config(self.vae_encoder_model_dir) - self.xB = 2 if do_classifier_free_guidance else 1 # batch multiplier - - def get_model(self, torch_inference=""): - vae_encoder = TorchVAEEncoder( - self.version, - self.pipeline, - self.hf_token, - self.device, - self.path, - self.framework_model_dir, - self.subfolder, - self.fp16, - self.bf16, - hf_safetensor=self.hf_safetensor, - ) - return vae_encoder - - def get_input_names(self): - return ["images"] - - def get_output_names(self): - return ["latent"] - - def get_dynamic_axes(self): - xB = "2B" if self.xB == 2 else "B" - return {"images": {0: xB, 2: "8H", 3: "8W"}, "latent": {0: xB, 2: "H", 3: "W"}} - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - assert batch_size >= self.min_batch and batch_size <= self.max_batch - min_batch = batch_size if static_batch else self.min_batch - max_batch = batch_size if static_batch else self.max_batch - self.check_dims(batch_size, image_height, image_width) - min_batch, max_batch, min_image_height, max_image_height, min_image_width, max_image_width, _, _, _, _ = ( - self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - ) - - if self.version == "flux.1-kontext-dev": - FluxKontextUtil = _get_flux_kontext_util() - min_latent_dim, max_latent_dim = FluxKontextUtil.get_min_max_kontext_dimensions() - return { - "images": [ - (self.xB * min_batch, 3, min_latent_dim[1], min_latent_dim[0]), - (self.xB * batch_size, 3, self.kontext_resolution[1], self.kontext_resolution[0]), - (self.xB * max_batch, 3, max_latent_dim[1], max_latent_dim[0]), - ], - } - return { - "images": [ - (self.xB * min_batch, 3, min_image_height, min_image_width), - (self.xB * batch_size, 3, image_height, image_width), - (self.xB * max_batch, 3, max_image_height, max_image_width), - ], - } - - def get_shape_dict(self, batch_size, image_height, image_width): - # Determine dimensions based on version - if self.version == "flux.1-kontext-dev": - img_h, img_w = self.kontext_resolution[1], self.kontext_resolution[0] - else: - img_h, img_w = image_height, image_width - latent_height, latent_width = self.check_dims(batch_size, img_h, img_w) - - return { - "images": (self.xB * batch_size, 3, img_h, img_w), - "latent": (self.xB * batch_size, self.config["latent_channels"], latent_height, latent_width), - } - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - self.check_dims(batch_size, image_height, image_width) - dtype = torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32 - return torch.randn(self.xB * batch_size, 3, image_height, image_width, dtype=dtype, device=self.device) - - -class SD3_VAEEncoderModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - max_batch_size, - fp16=False, - ): - super(SD3_VAEEncoderModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - max_batch_size=max_batch_size, - ) - self.subfolder = "sd3" - - def get_model(self, torch_inference=""): - dtype = torch.float16 if self.fp16 else torch.float32 - sd3_model_dir = load.get_checkpoint_dir(self.framework_model_dir, self.version, self.pipeline, self.subfolder) - sd3_filename = "sd3_medium.safetensors" - sd3_model_path = f"{sd3_model_dir}/{sd3_filename}" - if not os.path.exists(sd3_model_path): - hf_hub_download(repo_id=self.path, filename=sd3_filename, local_dir=sd3_model_dir) - with safe_open(sd3_model_path, framework="pt", device=self.device) as f: - model = SDVAE(device=self.device, dtype=dtype).eval().cuda() - prefix = "" - if any(k.startswith("first_stage_model.") for k in f.keys()): - prefix = "first_stage_model." - load_into(f, model, prefix, self.device, dtype) - model.forward = model.encode - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return ["images"] - - def get_output_names(self): - return ["latent"] - - def get_dynamic_axes(self): - return {"images": {0: "B", 2: "8H", 3: "8W"}, "latent": {0: "B", 2: "H", 3: "W"}} - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - min_batch, max_batch, _, _, _, _, _, _, _, _ = self.get_minmax_dims( - batch_size, image_height, image_width, static_batch, static_shape - ) - return { - "images": [ - (min_batch, 3, image_height, image_width), - (batch_size, 3, image_height, image_width), - (max_batch, 3, image_height, image_width), - ] - } - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - return { - "images": (batch_size, 3, image_height, image_width), - "latent": (batch_size, 16, latent_height, latent_width), - } - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - dtype = torch.float16 if self.fp16 else torch.float32 - return torch.randn(batch_size, 3, image_height, image_width, dtype=dtype, device=self.device) - - -class AutoencoderKLWanModel(base_model.BaseModel): - - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - tf32=False, - bf16=False, - max_batch_size=16, - ): - super(AutoencoderKLWanModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - tf32=tf32, - bf16=bf16, - max_batch_size=max_batch_size, - ) - self.is_wan_pipeline = version.startswith("wan") - self.subfolder = "vae" - self.vae_decoder_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - if not os.path.exists(self.vae_decoder_model_dir): - self.config = AutoencoderKLWan.load_config(self.path, subfolder=self.subfolder, token=self.hf_token) - else: - print(f"[I] Load AutoencoderKLWan (decoder) config from: {self.vae_decoder_model_dir}") - self.config = AutoencoderKLWan.load_config(self.vae_decoder_model_dir) - - def get_model(self, torch_inference=""): - if self.is_wan_pipeline: - print(f"[I] Using float32 precision for Wan 2.2 VAE decoder") - model_opts = {"torch_dtype": torch.float32} - else: - model_opts = ( - {"torch_dtype": torch.float16} if self.fp16 else {"torch_dtype": torch.bfloat16} if self.bf16 else {} - ) - if not load.is_model_cached(self.vae_decoder_model_dir, model_opts, self.hf_safetensor): - model = AutoencoderKLWan.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - model.save_pretrained(self.vae_decoder_model_dir, **model_opts) - else: - print(f"[I] Load AutoencoderKLWan (decoder) model from: {self.vae_decoder_model_dir}") - model = AutoencoderKLWan.from_pretrained(self.vae_decoder_model_dir, **model_opts).to(self.device) - model.forward = model.decode - model = optimizer.optimize_checkpoint(model, torch_inference) - return model - - def get_input_names(self): - return ["latent"] - - def get_output_names(self): - return ["images"] - - def get_dynamic_axes(self): - return {"latent": {0: "B", 3: "H", 4: "W"}, "images": {0: "B", 3: "8H", 4: "8W"}} - - def get_input_profile(self, batch_size, image_height, image_width, static_batch, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - min_batch, max_batch, _, _, _, _, min_latent_height, max_latent_height, min_latent_width, max_latent_width = ( - self.get_minmax_dims(batch_size, image_height, image_width, static_batch, static_shape) - ) - return { - "latent": [ - (min_batch, self.config["z_dim"], 1, min_latent_height, min_latent_width), - (batch_size, self.config["z_dim"], 1, latent_height, latent_width), - (max_batch, self.config["z_dim"], 1, max_latent_height, max_latent_width), - ] - } - - def get_shape_dict(self, batch_size, image_height, image_width): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - return { - "latent": (batch_size, self.config["z_dim"], 1, latent_height, latent_width), - "images": (batch_size, 3, 1, image_height, image_width), - } - - def get_sample_input(self, batch_size, image_height, image_width, static_shape): - latent_height, latent_width = self.check_dims(batch_size, image_height, image_width) - dtype = torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32 - return torch.randn( - batch_size, self.config["z_dim"], 1, latent_height, latent_width, dtype=dtype, device=self.device - ) - -class AutoencoderKLWanEncoderModelWrapper(torch.nn.Module): - def __init__(self, model): - super().__init__() - self.model = model - - def forward(self, x): - return self.model.encode(x).latent_dist.sample() - - -class AutoencoderKLWanEncoderModel(base_model.BaseModel): - def __init__( - self, - version, - pipeline, - device, - hf_token, - verbose, - framework_model_dir, - fp16=False, - tf32=False, - bf16=False, - max_batch_size=16, - ): - super(AutoencoderKLWanEncoderModel, self).__init__( - version, - pipeline, - device=device, - hf_token=hf_token, - verbose=verbose, - framework_model_dir=framework_model_dir, - fp16=fp16, - tf32=tf32, - bf16=bf16, - max_batch_size=max_batch_size, - ) - self.subfolder = "vae" - self.vae_encoder_model_dir = load.get_checkpoint_dir( - self.framework_model_dir, self.version, self.pipeline, self.subfolder - ) - if not os.path.exists(self.vae_encoder_model_dir): - self.config = AutoencoderKLWan.load_config(self.path, subfolder=self.subfolder, token=self.hf_token) - else: - print(f"[I] Load AutoencoderKLWan (encoder) config from: {self.vae_encoder_model_dir}") - self.config = AutoencoderKLWan.load_config(self.vae_encoder_model_dir) - - def get_model(self, torch_inference=""): - model_opts = ( - {"torch_dtype": torch.float16} if self.fp16 else {"torch_dtype": torch.bfloat16} if self.bf16 else {} - ) - if not load.is_model_cached(self.vae_encoder_model_dir, model_opts, self.hf_safetensor): - model = AutoencoderKLWan.from_pretrained( - self.path, - subfolder=self.subfolder, - use_safetensors=self.hf_safetensor, - token=self.hf_token, - **model_opts, - ).to(self.device) - model.save_pretrained(self.vae_encoder_model_dir, **model_opts) - else: - print(f"[I] Load AutoencoderKLWan (encoder) model from: {self.vae_encoder_model_dir}") - model = AutoencoderKLWan.from_pretrained(self.vae_encoder_model_dir, **model_opts).to(self.device) - model = AutoencoderKLWanEncoderModelWrapper(model) - model = optimizer.optimize_checkpoint(model, torch_inference) - return model diff --git a/demo/Diffusion/demo_diffusion/path/__init__.py b/demo/Diffusion/demo_diffusion/path/__init__.py deleted file mode 100644 index d9afdfb7e..000000000 --- a/demo/Diffusion/demo_diffusion/path/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from demo_diffusion.path.dd_path import DDPath -from demo_diffusion.path.resolve_path import resolve_path - -__all__ = ["DDPath", "resolve_path"] diff --git a/demo/Diffusion/demo_diffusion/path/dd_path.py b/demo/Diffusion/demo_diffusion/path/dd_path.py deleted file mode 100644 index d30b23a23..000000000 --- a/demo/Diffusion/demo_diffusion/path/dd_path.py +++ /dev/null @@ -1,50 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -""" -Define a data structure for storing various paths used in DemoDiffusion. -""" - -import dataclasses -import os -from typing import Dict - - -@dataclasses.dataclass -class DDPath: - """Data class that stores various paths used in DemoDiffusion.""" - - model_name_to_optimized_onnx_path: Dict[str, str] = dataclasses.field(default_factory=dict) - model_name_to_engine_path: Dict[str, str] = dataclasses.field(default_factory=dict) - - # Artifact paths. - model_name_to_unoptimized_onnx_path: Dict[str, str] = dataclasses.field(default_factory=dict) - model_name_to_weights_map_path: Dict[str, str] = dataclasses.field(default_factory=dict) - model_name_to_refit_weights_path: Dict[str, str] = dataclasses.field(default_factory=dict) - model_name_to_quantized_model_state_dict_path: Dict[str, str] = dataclasses.field(default_factory=dict) - - def create_directory(self) -> None: - """Create directories for all paths, if they do not exist.""" - all_paths = [value for name_to_path in dataclasses.astuple(self) for value in name_to_path.values()] - - for path in all_paths: - directory = os.path.dirname(path) - - # If `path` does not have a directory component, `directory` will be an empty string. - # Only proceed if `directory` is non-empty. - if directory: - os.makedirs(directory, exist_ok=True) diff --git a/demo/Diffusion/demo_diffusion/path/resolve_path.py b/demo/Diffusion/demo_diffusion/path/resolve_path.py deleted file mode 100644 index 292344259..000000000 --- a/demo/Diffusion/demo_diffusion/path/resolve_path.py +++ /dev/null @@ -1,168 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from __future__ import annotations - -import argparse -import hashlib -import os -from typing import Dict, List - -import tensorrt as trt - -from demo_diffusion import pipeline -from demo_diffusion.path import dd_path - -ARTIFACT_CACHE_DIRECTORY = os.path.join(os.getcwd(), "artifacts_cache") - - -def resolve_path( - model_names: List[str], - args: argparse.Namespace, - pipeline_type: pipeline.PIPELINE_TYPE, - pipeline_uid: str, -) -> dd_path.DDPath: - """Resolve all paths and store them in a newly constructed dd_path.DDPath object. - - Args: - model_names (List[str]): List of model names. - args (argparse.Namespace): Parsed arguments. - - Returns: - dd_path.DDPath: Path object containing all the resolved paths. - """ - path = dd_path.DDPath() - model_name_to_model_uri = { - model_name: _resolve_model_uri(model_name, args, pipeline_type, pipeline_uid) for model_name in model_names - } - - _resolve_default_path(model_name_to_model_uri, args, path) - _resolve_custom_path(args, path) - - path.create_directory() - - return path - - -def _resolve_model_uri( - model_name: str, args: argparse.Namespace, pipeline_type: pipeline.PIPELINE_TYPE, pipeline_uid: str -) -> str: - """Resolve and return the model URI. - - The model URI is a partial path that uniquely identifies the model. It is used to construct various model paths like - artifact cache path, checkpoint path, etc. - """ - # Lora unique ID represents the lora configuration. - if args.lora_path and args.lora_weight: - lora_config_uid = "-".join( - sorted( - [ - f"{hashlib.sha256(lora_path.encode()).hexdigest()}-{lora_weight}-{args.lora_scale}" - for lora_path, lora_weight in zip(args.lora_path, args.lora_weight) - if args.lora_path - ] - ) - ) - else: - lora_config_uid = "" - - # Quantization config unique ID represents the quantization configuration. - def _is_quantized() -> bool: - """Return True if model is quantized, False if otherwise. - - When quantization flags are set in `args`, only a subset of the models are actually quantized. - """ - is_unet = model_name == "unet" - is_unetxl_base = pipeline_type.is_sd_xl_base() and model_name == "unetxl" - is_flux_transformer = args.version.startswith("flux.1") and model_name == "transformer" - - if args.int8: - return is_unet or is_unetxl_base - elif args.fp8: - return is_unet or is_unetxl_base or is_flux_transformer - elif args.fp4: - return is_flux_transformer - else: - return False - - if _is_quantized(): - if args.int8 or args.fp8: - quantization_config_uid = ( - f"{'int8' if args.int8 else 'fp8'}.l{args.quantization_level}.bs2" - f".c{args.calibration_size}.p{args.quantization_percentile}.a{args.quantization_alpha}" - ) - else: - quantization_config_uid = "fp4" - else: - quantization_config_uid = "" - - # Model unique ID represents the model name and its configuration. It is unique under the same pipeline. - model_uid = "_".join([s for s in [model_name, lora_config_uid, quantization_config_uid] if s]) - - # Model URI is the concatenation of pipeline unique ID and model unique ID. - model_uri = os.path.join(pipeline_uid, model_uid) - - return model_uri - - -def _resolve_default_path( - model_name_to_model_uri: Dict[str, str], args: argparse.Namespace, path: dd_path.DDPath -) -> None: - """Resolve the default paths. - - Args: - model_name_to_model_uri (Dict[str, str]): Dictionary of model name to model URI. - args (argparse.Namespace): Parsed arguments. - path (dd_path.DDPath): Path object. This object is modified in-place to store all resolved default paths. - """ - for model_name, model_uri in model_name_to_model_uri.items(): - path.model_name_to_optimized_onnx_path[model_name] = os.path.join( - args.onnx_dir, model_uri, "model_optimized.onnx" - ) - path.model_name_to_engine_path[model_name] = os.path.join( - args.engine_dir, model_uri, f"engine_trt{trt.__version__}.plan" - ) - - # Resolve artifact paths. - artifact_dir = os.path.join(ARTIFACT_CACHE_DIRECTORY, model_uri) - - path.model_name_to_unoptimized_onnx_path[model_name] = os.path.join(artifact_dir, "model_unoptimized.onnx") - path.model_name_to_weights_map_path[model_name] = os.path.join(artifact_dir, "weights_map.json") - path.model_name_to_refit_weights_path[model_name] = os.path.join(artifact_dir, "refit_weights.json") - path.model_name_to_quantized_model_state_dict_path[model_name] = os.path.join( - artifact_dir, "quantized_model_state_dict.json" - ) - - -def _resolve_custom_path(args: argparse.Namespace, path: dd_path.DDPath) -> None: - """Resolve the custom paths. - - If a different path already exists in `path`, it will be overridden. - - Args: - args (argparse.Namespace): Parsed arguments. - path (dd_path.DDPath): Path object. This object is modified in-place to store or override all resolved paths. - """ - # Resolve and override custom ONNX paths. - if args.custom_onnx_paths: - for model_name, optimized_onnx_path in args.custom_onnx_paths.items(): - path.model_name_to_optimized_onnx_path[model_name] = optimized_onnx_path - - # Resolve and override custom engine paths. - if args.custom_engine_paths: - for model_name, engine_path in args.custom_engine_paths.items(): - path.model_name_to_engine_path[model_name] = engine_path diff --git a/demo/Diffusion/demo_diffusion/pipeline/__init__.py b/demo/Diffusion/demo_diffusion/pipeline/__init__.py deleted file mode 100644 index be26bee41..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/__init__.py +++ /dev/null @@ -1,104 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import importlib -from typing import TYPE_CHECKING - -# Expose public API while avoiding importing optional dependencies at module import time. -# Each attribute is imported on first access via __getattr__. - -__all__ = [ - "DiffusionPipeline", - "FluxPipeline", - "FluxKontextPipeline", - "StableCascadePipeline", - "StableDiffusion3Pipeline", - "StableDiffusion35Pipeline", - "StableDiffusionPipeline", - "CosmosPipeline", - "StableVideoDiffusionPipeline", - "WanPipeline", - "PIPELINE_TYPE", -] - -_LAZY_ATTRS = { - # Core/base - "DiffusionPipeline": ("demo_diffusion.pipeline.diffusion_pipeline", "DiffusionPipeline"), - "PIPELINE_TYPE": ("demo_diffusion.pipeline.type", "PIPELINE_TYPE"), - # Stable Diffusion family - "StableDiffusionPipeline": ("demo_diffusion.pipeline.stable_diffusion_pipeline", "StableDiffusionPipeline"), - "StableDiffusion3Pipeline": ("demo_diffusion.pipeline.stable_diffusion_3_pipeline", "StableDiffusion3Pipeline"), - "StableDiffusion35Pipeline": ("demo_diffusion.pipeline.stable_diffusion_35_pipeline", "StableDiffusion35Pipeline"), - # Stable Cascade - "StableCascadePipeline": ("demo_diffusion.pipeline.stable_cascade_pipeline", "StableCascadePipeline"), - # Stable Video Diffusion - "StableVideoDiffusionPipeline": ("demo_diffusion.pipeline.stable_video_diffusion_pipeline", "StableVideoDiffusionPipeline"), - # Flux family (optional dependency: `flux`) - "FluxPipeline": ("demo_diffusion.pipeline.flux_pipeline", "FluxPipeline"), - "FluxKontextPipeline": ("demo_diffusion.pipeline.flux_pipeline", "FluxKontextPipeline"), - # Cosmos (optional dependency: `flux`) - "CosmosPipeline": ("demo_diffusion.pipeline.cosmos_pipeline", "CosmosPipeline"), - # Wan - "WanPipeline": ("demo_diffusion.pipeline.wan_pipeline", "WanPipeline"), -} - -def __getattr__(name): - if name not in _LAZY_ATTRS: - raise AttributeError(f"module 'demo_diffusion.pipeline' has no attribute {name!r}") - - module_path, attr_name = _LAZY_ATTRS[name] - try: - module = importlib.import_module(module_path) - except ModuleNotFoundError as e: - missing_pkg = e.name or "" - raise ModuleNotFoundError( - f"Optional dependency '{missing_pkg}' is required for '{name}'. " - "Install the appropriate extras/requirements for the selected pipeline " - "(e.g., use the non-legacy requirements for Flux/Cosmos), or install the missing package." - ) from e - try: - return getattr(module, attr_name) - except AttributeError as e: - raise AttributeError( - f"'{module_path}' does not export attribute '{attr_name}' (while resolving '{name}')." - ) from e - - -if TYPE_CHECKING: - from demo_diffusion.pipeline.diffusion_pipeline import DiffusionPipeline as DiffusionPipeline - from demo_diffusion.pipeline.type import PIPELINE_TYPE as PIPELINE_TYPE - from demo_diffusion.pipeline.stable_diffusion_pipeline import ( - StableDiffusionPipeline as StableDiffusionPipeline, - ) - from demo_diffusion.pipeline.stable_diffusion_3_pipeline import ( - StableDiffusion3Pipeline as StableDiffusion3Pipeline, - ) - from demo_diffusion.pipeline.stable_diffusion_35_pipeline import ( - StableDiffusion35Pipeline as StableDiffusion35Pipeline, - ) - from demo_diffusion.pipeline.stable_cascade_pipeline import ( - StableCascadePipeline as StableCascadePipeline, - ) - from demo_diffusion.pipeline.stable_video_diffusion_pipeline import ( - StableVideoDiffusionPipeline as StableVideoDiffusionPipeline, - ) - # Optional pipelines - from demo_diffusion.pipeline.flux_pipeline import ( - FluxPipeline as FluxPipeline, - FluxKontextPipeline as FluxKontextPipeline, - ) - from demo_diffusion.pipeline.cosmos_pipeline import CosmosPipeline as CosmosPipeline - from demo_diffusion.pipeline.wan_pipeline import WanPipeline as WanPipeline diff --git a/demo/Diffusion/demo_diffusion/pipeline/calibrate.py b/demo/Diffusion/demo_diffusion/pipeline/calibrate.py deleted file mode 100644 index 29d9bdcca..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/calibrate.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import os - -from diffusers.utils import load_image - - -def load_calib_prompts(batch_size, calib_data_path): - with open(calib_data_path, "r", encoding="utf-8") as file: - lst = [line.rstrip("\n") for line in file] - return [lst[i : i + batch_size] for i in range(0, len(lst), batch_size)] - - -def load_calibration_images(folder_path): - images = [] - for filename in os.listdir(folder_path): - img_path = os.path.join(folder_path, filename) - if os.path.isfile(img_path): - image = load_image(img_path) - if image is not None: - images.append(image) - return images diff --git a/demo/Diffusion/demo_diffusion/pipeline/cosmos_pipeline.py b/demo/Diffusion/demo_diffusion/pipeline/cosmos_pipeline.py deleted file mode 100644 index e67691888..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/cosmos_pipeline.py +++ /dev/null @@ -1,1007 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from __future__ import annotations - -import argparse -import inspect -import os -import random -import time -import warnings -from typing import Any, List - -import numpy as np -import tensorrt as trt -import torch -from cuda.bindings import runtime as cudart -from diffusers.video_processor import VideoProcessor -from flux.content_filters import PixtralContentFilter -from tqdm import tqdm - -from demo_diffusion import path as path_module -from demo_diffusion.model import ( - AutoencoderKLWanEncoderModel, - AutoencoderKLWanModel, - CosmosTransformerModel, - T5Model, - make_tokenizer, -) -from demo_diffusion.pipeline.diffusion_pipeline import DiffusionPipeline -from demo_diffusion.pipeline.type import PIPELINE_TYPE - -TRT_LOGGER = trt.Logger(trt.Logger.ERROR) - - -class CosmosPipeline(DiffusionPipeline): - """ - Application showcasing the acceleration of Cosmos pipelines using Nvidia TensorRT. - """ - - def __init__( - self, - version="cosmos-predict2-2b", - pipeline_type=PIPELINE_TYPE.TXT2IMG, - guidance_scale=6.0, - max_sequence_length=512, - t5_weight_streaming_budget_percentage=None, - transformer_weight_streaming_budget_percentage=None, - **kwargs, - ): - """ - Initializes the Cosmos pipeline. - - Args: - version (`str`, defaults to `cosmos-1.0-7B`) - Version of the underlying Cosmos model. - guidance_scale (`float`, defaults to 3.5): - Guidance scale is enabled by setting as > 1. - Higher guidance scale encourages to generate images that are closely linked to the text prompt, usually at the expense of lower image quality. - max_sequence_length (`int`, defaults to 512): - Maximum sequence length to use with the `prompt`. - t5_weight_streaming_budget_percentage (`int`, defaults to None): - Weight streaming budget as a percentage of the size of total streamable weights for the T5 model. - transformer_weight_streaming_budget_percentage (`int`, defaults to None): - Weight streaming budget as a percentage of the size of total streamable weights for the Transformer model. - """ - super().__init__( - version=version, - pipeline_type=pipeline_type, - text_encoder_weight_streaming_budget_percentage=t5_weight_streaming_budget_percentage, - denoiser_weight_streaming_budget_percentage=transformer_weight_streaming_budget_percentage, - **kwargs, - ) - self.guidance_scale = guidance_scale - self.max_sequence_length = max_sequence_length - self.do_classifier_free_guidance = self.guidance_scale > 1 - - # WAR ONNX export error: Exporting the operator 'aten::_upsample_nearest_exact2d' to ONNX opset version 19 is not supported - self.config["vae_torch_fallback"] = True - self.config["vae_encoder_torch_fallback"] = True - - @classmethod - def FromArgs(cls, args: argparse.Namespace, pipeline_type: PIPELINE_TYPE) -> CosmosPipeline: - """Factory method to construct a `CosmosPipeline` object from parsed arguments. - - Overrides: - DiffusionPipeline.FromArgs - """ - MAX_BATCH_SIZE = 4 - DEVICE = "cuda" - DO_RETURN_LATENTS = False - - # Resolve all paths. - dd_path = path_module.resolve_path( - cls.get_model_names(pipeline_type), args, pipeline_type, cls._get_pipeline_uid(args.version) - ) - - return cls( - dd_path=dd_path, - version=args.version, - pipeline_type=pipeline_type, - guidance_scale=args.guidance_scale, - max_sequence_length=args.max_sequence_length, - bf16=args.bf16, - low_vram=args.low_vram, - torch_fallback=args.torch_fallback, - weight_streaming=args.ws, - t5_weight_streaming_budget_percentage=args.t5_ws_percentage, - transformer_weight_streaming_budget_percentage=args.transformer_ws_percentage, - max_batch_size=MAX_BATCH_SIZE, - denoising_steps=args.denoising_steps, - scheduler=args.scheduler, - device=DEVICE, - output_dir=args.output_dir, - hf_token=args.hf_token, - verbose=args.verbose, - nvtx_profile=args.nvtx_profile, - use_cuda_graph=args.use_cuda_graph, - framework_model_dir=args.framework_model_dir, - return_latents=DO_RETURN_LATENTS, - torch_inference=args.torch_inference, - ) - - @classmethod - def get_model_names(cls, pipeline_type: PIPELINE_TYPE, controlnet_type: str = None) -> List[str]: - """Return a list of model names used by this pipeline. - - Overrides: - DiffusionPipeline.get_model_names - """ - if pipeline_type.is_video2world(): - return ["vae_encoder", "t5", "transformer", "vae"] - return ["t5", "transformer", "vae"] - - def download_onnx_models(self, model_name: str, model_config: dict[str, Any]) -> None: - raise ValueError("ONNX models download is not supported for the Cosmos Pipeline") - - def _initialize_models(self, framework_model_dir, int8, fp8, fp4): - # Load text tokenizer(s) - self.tokenizer = make_tokenizer( - self.version, self.pipeline_type, self.hf_token, framework_model_dir, tokenizer_type="t5" - ) - - # Load pipeline models - models_args = { - "version": self.version, - "pipeline": self.pipeline_type, - "device": self.device, - "hf_token": self.hf_token, - "verbose": self.verbose, - "framework_model_dir": framework_model_dir, - "max_batch_size": self.max_batch_size, - } - - self.fp16 = True if not self.bf16 else False - self.tf32 = True - if "t5" in self.stages: - # Known accuracy issues with FP16 - self.models["t5"] = T5Model( - **models_args, - fp16=self.fp16, - tf32=self.tf32, - bf16=self.bf16, - text_maxlen=self.max_sequence_length, - use_attention_mask=True, - ) - - if "transformer" in self.stages: - self.models["transformer"] = CosmosTransformerModel( - **models_args, - bf16=self.bf16, - fp16=self.fp16, - int8=int8, - fp8=fp8, - tf32=self.tf32, - text_maxlen=self.max_sequence_length, - weight_streaming=self.weight_streaming, - weight_streaming_budget_percentage=self.denoiser_weight_streaming_budget_percentage, - ) - - if "vae" in self.stages: - self.models["vae"] = AutoencoderKLWanModel(**models_args, fp16=False, tf32=self.tf32, bf16=self.bf16) - - if "vae_encoder" in self.stages: - self.models["vae_encoder"] = AutoencoderKLWanEncoderModel( - **models_args, fp16=False, tf32=self.tf32, bf16=self.bf16 - ) - - self.vae_scale_factor_temporal = ( - 2 ** sum(self.models["vae"].config["temperal_downsample"]) - if "vae" in self.stages and self.models["vae"] is not None - else 4 - ) - self.vae_scale_factor_spatial = ( - 2 ** len(self.models["vae"].config["temperal_downsample"]) - if "vae" in self.stages and self.models["vae"] is not None - else 8 - ) - - self.video_processor = VideoProcessor(vae_scale_factor=self.vae_scale_factor_spatial) - - def encode_video(self, video): - self.profile_start("vae_encoder", color="red") - cast_to = ( - torch.float16 - if self.models["vae_encoder"].fp16 - else torch.bfloat16 if self.models["vae_encoder"].bf16 else torch.float32 - ) - video = video.to(dtype=cast_to) - if self.torch_inference: - image_latents = self.torch_models["vae_encoder"](video) - else: - image_latents = self.run_engine("vae_encoder", {"images": video})["latent"] - self.profile_stop("vae_encoder") - return image_latents - - def initialize_latents_text2image( - self, - batch_size, - num_channels_latents, - num_latent_frames, - latent_height, - latent_width, - latents_dtype=torch.float32, - ): - latents_shape = (batch_size, num_channels_latents, num_latent_frames, latent_height, latent_width) - latents = torch.randn( - latents_shape, - device=self.device, - dtype=latents_dtype, - generator=self.generator, - ) - - return latents * self.scheduler.config.sigma_max - - def initialize_latents_video2world( - self, - video, - batch_size, - num_channels_latents, - num_frames, - latent_height, - latent_width, - latents_dtype=torch.float32, - do_classifier_free_guidance=False, - ): - num_cond_frames = video.size(2) - if num_cond_frames >= num_frames: - # Take the last `num_frames` frames for conditioning - num_cond_latent_frames = (num_frames - 1) // self.vae_scale_factor_temporal + 1 - video = video[:, :, -num_frames:] - else: - num_cond_latent_frames = (num_cond_frames - 1) // self.vae_scale_factor_temporal + 1 - num_padding_frames = num_frames - num_cond_frames - last_frame = video[:, :, -1:] - padding = last_frame.repeat(1, 1, num_padding_frames, 1, 1) - video = torch.cat([video, padding], dim=2) - - # Encode video - with self.model_memory_manager(["vae_encoder"], low_vram=self.low_vram): - video_latents = self.encode_video( - video=video, - ) - - latents_mean = ( - torch.tensor(self.models["vae"].config["latents_mean"]) - .view(1, self.models["vae"].config["z_dim"], 1, 1, 1) - .to(self.device, latents_dtype) - ) - latents_std = ( - torch.tensor(self.models["vae"].config["latents_std"]) - .view(1, self.models["vae"].config["z_dim"], 1, 1, 1) - .to(self.device, latents_dtype) - ) - init_latents = (video_latents - latents_mean) / latents_std * self.scheduler.config.sigma_data - - num_latent_frames = (num_frames - 1) // self.vae_scale_factor_temporal + 1 - shape = (batch_size, num_channels_latents, num_latent_frames, latent_height, latent_width) - - latents = torch.randn( - shape, - device=self.device, - dtype=latents_dtype, - generator=self.generator, - ) - - latents = latents * self.scheduler.config.sigma_max - - padding_shape = (batch_size, 1, num_latent_frames, latent_height, latent_width) - ones_padding = latents.new_ones(padding_shape) - zeros_padding = latents.new_zeros(padding_shape) - - cond_indicator = latents.new_zeros(1, 1, latents.size(2), 1, 1) - cond_indicator[:, :, :num_cond_latent_frames] = 1.0 - cond_mask = cond_indicator * ones_padding + (1 - cond_indicator) * zeros_padding - - uncond_indicator = uncond_mask = None - if do_classifier_free_guidance: - uncond_indicator = latents.new_zeros(1, 1, latents.size(2), 1, 1) - uncond_indicator[:, :, :num_cond_latent_frames] = 1.0 - uncond_mask = uncond_indicator * ones_padding + (1 - uncond_indicator) * zeros_padding - - return latents, init_latents, cond_indicator, uncond_indicator, cond_mask, uncond_mask - - # Copied from https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/flux/pipeline_flux_img2img.py#L416C1 - def get_timesteps(self, num_inference_steps, strength): - # get the original timestep using init_timestep - init_timestep = min(num_inference_steps * strength, num_inference_steps) - - t_start = int(max(num_inference_steps - init_timestep, 0)) - timesteps = self.scheduler.timesteps[t_start * self.scheduler.order :] - if hasattr(self.scheduler, "set_begin_index"): - self.scheduler.set_begin_index(t_start * self.scheduler.order) - - return timesteps, num_inference_steps - t_start - - def _duplicate_text_embeddings(self, batch_size, text_embeddings, num_outputs_per_prompt): - # duplicate text embeddings for each generation per prompt, using mps friendly method - _, seq_len, _ = text_embeddings.shape - text_embeddings = text_embeddings.repeat(1, num_outputs_per_prompt, 1) - text_embeddings = text_embeddings.view(batch_size * num_outputs_per_prompt, seq_len, -1) - return text_embeddings - - def _prepare_timesteps(self, num_inference_steps): - """Prepare timesteps for the scheduler.""" - sigmas_dtype = torch.float32 if torch.backends.mps.is_available() else torch.float64 - sigmas = torch.linspace(0, 1, num_inference_steps, dtype=sigmas_dtype) - accept_sigmas = "sigmas" in set(inspect.signature(self.scheduler.set_timesteps).parameters.keys()) - if not accept_sigmas: - raise ValueError( - f"The current scheduler class {self.scheduler.__class__}'s `set_timesteps` does not support custom" - f" sigmas schedules. Please check whether you are using the correct scheduler." - ) - self.scheduler.set_timesteps(sigmas=sigmas, device=self.device) - timesteps = self.scheduler.timesteps - num_inference_steps = len(timesteps) - if self.scheduler.config.get("final_sigmas_type", "zero") == "sigma_min": - # Replace the last sigma (which is zero) with the minimum sigma value - self.scheduler.sigmas[-1] = self.scheduler.sigmas[-2] - return timesteps, num_inference_steps - - def _encode_text_prompts(self, prompt, negative_prompt, batch_size, num_outputs_per_prompt): - """Encode text prompts using T5 encoder.""" - with self.model_memory_manager(["t5"], low_vram=self.low_vram): - text_embeddings = self.encode_prompt(prompt) - text_embeddings = self._duplicate_text_embeddings(batch_size, text_embeddings, num_outputs_per_prompt) - negative_text_embeddings = None - if self.do_classifier_free_guidance: - negative_text_embeddings = self.encode_prompt(negative_prompt) - negative_text_embeddings = self._duplicate_text_embeddings( - batch_size, negative_text_embeddings, num_outputs_per_prompt - ) - return text_embeddings, negative_text_embeddings - - def _get_latents_normalization_params(self, device, dtype): - """Get latents normalization parameters from VAE config.""" - latents_mean = ( - torch.tensor(self.models["vae"].config["latents_mean"]) - .view(1, self.models["vae"].config["z_dim"], 1, 1, 1) - .to(device, dtype) - ) - latents_std = ( - torch.tensor(self.models["vae"].config["latents_std"]) - .view(1, self.models["vae"].config["z_dim"], 1, 1, 1) - .to(device, dtype) - ) - return latents_mean, latents_std - - def _normalize_and_decode_latents(self, latents, is_video2world=False): - """Normalize latents and decode using VAE.""" - latents_mean, latents_std = self._get_latents_normalization_params(latents.device, latents.dtype) - - if is_video2world: - # For video2world: latents * std / sigma_data + mean - latents = latents * latents_std / self.scheduler.config.sigma_data + latents_mean - else: - # For text2image: latents / (1/std) / sigma_data + mean - latents_std_inv = 1.0 / latents_std - latents = latents / latents_std_inv / self.scheduler.config.sigma_data + latents_mean - - with self.model_memory_manager(["vae"], low_vram=self.low_vram): - video = self.decode_latent(latents) - - return video - - def encode_prompt(self, prompt, encoder="t5"): - self.profile_start(encoder, color="green") - - def tokenize(prompt): - text_inputs = self.tokenizer( - prompt, - padding="max_length", - max_length=self.max_sequence_length, - truncation=True, - return_overflowing_tokens=False, - return_length=False, - return_tensors="pt", - ) - text_input_ids = text_inputs.input_ids.to(self.device) - attention_mask = text_inputs.attention_mask.bool().to(self.device) - - untruncated_ids = self.tokenizer(prompt, padding="longest", return_tensors="pt").input_ids.to(self.device) - if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal( - text_input_ids, untruncated_ids - ): - removed_text = self.tokenizer.batch_decode(untruncated_ids[:, self.max_sequence_length - 1 : -1]) - warnings.warn( - "The following part of your input was truncated because `max_sequence_length` is set to " - f"{self.max_sequence_length} tokens: {removed_text}" - ) - - if self.torch_inference or self.torch_fallback[encoder]: - text_encoder_output = self.torch_models[encoder]( - text_input_ids, attention_mask=attention_mask - ).last_hidden_state - else: - # NOTE: output tensor for the encoder must be cloned because it will be overwritten when called again for prompt2 - text_encoder_output = self.run_engine( - encoder, {"input_ids": text_input_ids, "attention_mask": attention_mask} - )["text_embeddings"] - - lengths = attention_mask.sum(dim=1).cpu() - for i, length in enumerate(lengths): - text_encoder_output[i, length:] = 0 - return text_encoder_output - - # Tokenize prompt - text_encoder_output = tokenize(prompt) - - self.profile_stop(encoder) - return ( - text_encoder_output.to(torch.float16) - if self.fp16 - else text_encoder_output.to(torch.bfloat16) if self.bf16 else text_encoder_output.to(torch.float32) - ) - - def denoise_latent( - self, - latents, - timesteps, - text_embeddings, - negative_text_embeddings, - padding_mask, - denoiser="transformer", - ): - do_autocast = self.torch_inference != "" and self.models[denoiser].fp16 - with torch.autocast("cuda", enabled=do_autocast, dtype=torch.float32): - self.profile_start(denoiser, color="blue") - - for step_index, timestep in tqdm(enumerate(timesteps), total=len(timesteps), desc="Denoising"): - # Prepare latents - cast_to = ( - torch.float16 - if self.models[denoiser].fp16 - else torch.bfloat16 if self.models[denoiser].bf16 else torch.float32 - ) - current_sigma = self.scheduler.sigmas[step_index] - current_t = current_sigma / (current_sigma + 1) - c_in = 1 - current_t - c_skip = 1 - current_t - c_out = -current_t - timestep_inp = current_t.expand(latents.shape[0]).to(cast_to) # [B, 1, T, 1, 1] - latents_input = (latents * c_in).to(cast_to) - # prepare inputs - params = { - "hidden_states": latents_input, - "timestep": timestep_inp, - "encoder_hidden_states": text_embeddings, - "padding_mask": padding_mask, - } - - if self.torch_inference or self.torch_fallback[denoiser]: - noise_pred = self.torch_models[denoiser](**params)["sample"] - else: - noise_pred = self.run_engine(denoiser, params)["latent"].clone() - - noise_pred = (c_skip * latents + c_out * noise_pred.float()).to(cast_to) - if self.do_classifier_free_guidance: - params = { - "hidden_states": latents_input, - "timestep": timestep_inp, - "encoder_hidden_states": negative_text_embeddings, - "padding_mask": padding_mask, - } - - # Predict the noise residual - if self.torch_inference or self.torch_fallback[denoiser]: - noise_pred_uncond = self.torch_models[denoiser](**params)["sample"] - else: - noise_pred_uncond = self.run_engine(denoiser, params)["latent"].clone() - - noise_pred_uncond = (c_skip * latents + c_out * noise_pred_uncond.float()).to(cast_to) - noise_pred = noise_pred + self.guidance_scale * (noise_pred - noise_pred_uncond) - - noise_pred = (latents - noise_pred) / current_sigma - latents = self.scheduler.step(noise_pred, timestep, latents, return_dict=False)[0] - - self.profile_stop(denoiser) - return latents.to(dtype=torch.bfloat16) if self.bf16 else latents.to(dtype=torch.float32) - - def denoise_latent_video2world( - self, - latents, - timesteps, - text_embeddings, - negative_text_embeddings, - padding_mask, - fps, - cond_mask, - uncond_mask, - t_conditioning, - cond_indicator, - conditioning_latents, - uncond_indicator, - unconditioning_latents, - denoiser="transformer", - ): - do_autocast = self.torch_inference != "" and self.models[denoiser].fp16 - with torch.autocast("cuda", enabled=do_autocast, dtype=torch.float32): - self.profile_start(denoiser, color="blue") - - for step_index, timestep in tqdm(enumerate(timesteps), total=len(timesteps), desc="Denoising"): - # Prepare latents - cast_to = ( - torch.float16 - if self.models[denoiser].fp16 - else torch.bfloat16 if self.models[denoiser].bf16 else torch.float32 - ) - current_sigma = self.scheduler.sigmas[step_index] - current_t = current_sigma / (current_sigma + 1) - c_in = 1 - current_t - c_skip = 1 - current_t - c_out = -current_t - timestep_inp = current_t.view(1, 1, 1, 1, 1).expand( - latents.size(0), -1, latents.size(2), -1, -1 - ) # [B, 1, T, 1, 1] - latents_input = latents * c_in - latents_input = (cond_indicator * conditioning_latents + (1 - cond_indicator) * latents_input).to( - cast_to - ) - timestep_inp = (cond_indicator * t_conditioning + (1 - cond_indicator) * timestep_inp).to(cast_to) - - # prepare inputs - params = { - "hidden_states": latents_input, - "timestep": timestep_inp, - "encoder_hidden_states": text_embeddings, - "padding_mask": padding_mask, - "fps": fps, - "condition_mask": cond_mask, - } - - if self.torch_inference or self.torch_fallback[denoiser]: - noise_pred = self.torch_models[denoiser](**params)["sample"] - else: - noise_pred = self.run_engine(denoiser, params)["latent"].clone() - - noise_pred = (c_skip * latents + c_out * noise_pred.float()).to(cast_to) - noise_pred = cond_indicator * conditioning_latents + (1 - cond_indicator) * noise_pred - if self.do_classifier_free_guidance: - latents_input = latents * c_in - latents_input = ( - uncond_indicator * unconditioning_latents + (1 - uncond_indicator) * latents_input - ).to(cast_to) - timestep_inp = (uncond_indicator * t_conditioning + (1 - uncond_indicator) * timestep_inp).to( - cast_to - ) - params = { - "hidden_states": latents_input, - "timestep": timestep_inp, - "encoder_hidden_states": negative_text_embeddings, - "padding_mask": padding_mask, - "fps": fps, - "condition_mask": uncond_mask, - } - - # Predict the noise residual - if self.torch_inference or self.torch_fallback[denoiser]: - noise_pred_uncond = self.torch_models[denoiser](**params)["sample"] - else: - noise_pred_uncond = self.run_engine(denoiser, params)["latent"].clone() - - noise_pred_uncond = (c_skip * latents + c_out * noise_pred_uncond.float()).to(cast_to) - noise_pred_uncond = ( - uncond_indicator * unconditioning_latents + (1 - uncond_indicator) * noise_pred_uncond - ) - noise_pred = noise_pred + self.guidance_scale * (noise_pred - noise_pred_uncond) - - noise_pred = (latents - noise_pred) / current_sigma - latents = self.scheduler.step(noise_pred, timestep, latents, return_dict=False)[0] - - self.profile_stop(denoiser) - return latents.to(dtype=torch.bfloat16) if self.bf16 else latents.to(dtype=torch.float32) - - def decode_latent(self, latents, decoder="vae"): - self.profile_start(decoder, color="red") - cast_to = ( - torch.float16 - if self.models[decoder].fp16 - else torch.bfloat16 if self.models[decoder].bf16 else torch.float32 - ) - latents = latents.to(dtype=cast_to) - - if self.torch_inference or self.torch_fallback[decoder]: - video = self.torch_models[decoder](latents, return_dict=False)[0] - else: - video = self.run_engine(decoder, {"latent": latents})["frames"] - - self.profile_stop(decoder) - return video - - def post_process_video(self, video): - # Post-process video - video = self.video_processor.postprocess_video(video, output_type="np") - video = (video * 255).astype(np.uint8) - video_batch = [] - for vid in video: - # vid = self.safety_checker.check_video_safety(vid) - video_batch.append(vid) - video = np.stack(video_batch).astype(np.float32) / 255.0 * 2 - 1 - video = torch.from_numpy(video).permute(0, 4, 1, 2, 3) - video = self.video_processor.postprocess_video(video, output_type="pil") - - if self.pipeline_type.is_video2world(): - return video - - image = [batch[0] for batch in video] - if isinstance(video, torch.Tensor): - image = torch.stack(image) - elif isinstance(video, np.ndarray): - image = np.stack(image) - - return image - - def _finalize_generation(self, video, walltime_ms, num_inference_steps, batch_size, warmup, save_output): - """Handle post-processing, saving, and performance reporting.""" - if not warmup: - self.print_summary(num_inference_steps, walltime_ms, batch_size) - if not self.return_latents and save_output: - # post-process video - processed_output = self.post_process_video(video) - - # save output - if self.pipeline_type.is_video2world(): - return (processed_output[0], walltime_ms) - return (np.array(processed_output), walltime_ms) - - def _check_integrity(self, images): - integrity_checker = PixtralContentFilter(self.device) - for image in images: - image_ = np.array(image) / 255.0 - image_ = 2 * image_ - 1 - image_ = torch.from_numpy(image_).to(self.device, dtype=torch.float32).permute(0, 3, 1, 2) - if integrity_checker.test_image(image_): - raise ValueError("Your image has been flagged. Choose another prompt/image or try again.") - - def save_images(self, prompt, images, check_integrity=False): - if check_integrity: - self._check_integrity(images) - for image in images: - self.save_image(image, self.pipeline_type.name.lower(), prompt, self.seed) - - def save_video( - self, - prompt, - videos, - check_integrity=False, - ): - for frames in videos: - if check_integrity: - self._check_integrity([frames]) - prompt_prefix = "".join(set([prompt[i].replace(" ", "_")[:10] for i in range(len(prompt))])) - video_name_prefix = "-".join( - [self.pipeline_type.name.lower(), "fp16", str(self.seed), str(random.randint(1000, 9999))] - ) - video_name_suffix = "torch" if self.torch_inference else "trt" - video_path = prompt_prefix + "-" + video_name_prefix + "-" + video_name_suffix + ".gif" - print(f"Saving video to: {video_path}") - frames[0].save( - os.path.join(self.output_dir, video_path), - save_all=True, - optimize=False, - append_images=frames[1:], - loop=0, - ) - - def print_summary(self, denoising_steps, walltime_ms, batch_size): - print("|-----------------|--------------|") - print("| {:^15} | {:^12} |".format("Module", "Latency")) - print("|-----------------|--------------|") - for stage in self.stages: - print( - "| {:^15} | {:>9.2f} ms |".format( - stage + " x " + str(denoising_steps) if stage == "transformer" else stage, - cudart.cudaEventElapsedTime(self.events[stage][0], self.events[stage][1])[1], - ) - ) - print("|-----------------|--------------|") - print("| {:^15} | {:>9.2f} ms |".format("Pipeline", walltime_ms)) - print("|-----------------|--------------|") - print("Throughput: {:.2f} image/s".format(batch_size * 1000.0 / walltime_ms)) - - def generate_image( - self, - prompt, - negative_prompt, - image_height, - image_width, - num_frames=1, - num_images_per_prompt=1, - save_image=True, - warmup=False, - ): - batch_size = len(prompt) - - # Spatial dimensions of latent tensor - num_latent_frames = (num_frames - 1) // self.vae_scale_factor_temporal + 1 - latent_height = image_height // self.vae_scale_factor_spatial - latent_width = image_width // self.vae_scale_factor_spatial - - num_inference_steps = self.denoising_steps - - with torch.inference_mode(), trt.Runtime(TRT_LOGGER): - torch.cuda.synchronize() - e2e_tic = time.perf_counter() - - # Prepare timesteps - timesteps, num_inference_steps = self._prepare_timesteps(num_inference_steps) - - # T5 text encoder - text_embeddings, negative_text_embeddings = self._encode_text_prompts( - prompt, negative_prompt, batch_size, num_images_per_prompt - ) - - num_channels_latents = self.models["transformer"].config["in_channels"] - latents_dtype = torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32 - - # Initialize latents - latents = self.initialize_latents_text2image( - batch_size=batch_size, - num_channels_latents=num_channels_latents, - num_latent_frames=num_latent_frames, - latent_height=latent_height, - latent_width=latent_width, - latents_dtype=latents_dtype, - ) - padding_mask = latents.new_zeros(1, 1, image_height, image_width, dtype=latents_dtype) - - # denoiser - with self.model_memory_manager(["transformer"], low_vram=self.low_vram): - latents = self.denoise_latent( - latents, - timesteps, - text_embeddings, - negative_text_embeddings, - padding_mask, - ) - - # VAE decode latent - video = self._normalize_and_decode_latents(latents, is_video2world=False) - - torch.cuda.synchronize() - e2e_toc = time.perf_counter() - - walltime_ms = (e2e_toc - e2e_tic) * 1000.0 - return self._finalize_generation( - video, - walltime_ms, - num_inference_steps, - batch_size, - warmup, - save_image, - ) - - def generate_video( - self, - prompt, - negative_prompt, - image_height, - image_width, - input_image=None, - input_video=None, - num_frames=1, - fps=16, - num_videos_per_prompt=1, - sigma_conditioning=0.0001, - save_video=True, - warmup=False, - ): - batch_size = len(prompt) - - # Spatial dimensions of latent tensor - latent_height = image_height // self.vae_scale_factor_spatial - latent_width = image_width // self.vae_scale_factor_spatial - - num_inference_steps = self.denoising_steps - - with torch.inference_mode(), trt.Runtime(TRT_LOGGER): - torch.cuda.synchronize() - e2e_tic = time.perf_counter() - - # Prepare timesteps - timesteps, num_inference_steps = self._prepare_timesteps(num_inference_steps) - - # T5 text encoder - text_embeddings, negative_text_embeddings = self._encode_text_prompts( - prompt, negative_prompt, batch_size, num_videos_per_prompt - ) - - num_channels_latents = self.models["transformer"].config["in_channels"] - 1 - latents_dtype = torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32 - - # Process input conditioning - if input_image is not None: - video = ( - self.video_processor.preprocess(input_image, image_height, image_width) - .unsqueeze(2) - .to(device=self.device, dtype=latents_dtype) - ) - elif input_video is not None: - video = self.video_processor.preprocess_video(input_video, image_height, image_width).to( - device=self.device, dtype=latents_dtype - ) - else: - raise ValueError("Video2world pipeline requires either input_image or input_video to be provided") - - # Initialize latents - latents, conditioning_latents, cond_indicator, uncond_indicator, cond_mask, uncond_mask = ( - self.initialize_latents_video2world( - video, - batch_size=batch_size, - num_channels_latents=num_channels_latents, - num_frames=num_frames, - latent_height=latent_height, - latent_width=latent_width, - latents_dtype=latents_dtype, - do_classifier_free_guidance=self.do_classifier_free_guidance, - ) - ) - unconditioning_latents = None - - cond_mask = cond_mask.to(latents_dtype) - if self.do_classifier_free_guidance: - uncond_mask = uncond_mask.to(latents_dtype) - unconditioning_latents = conditioning_latents - - padding_mask = latents.new_zeros(1, 1, image_height, image_width, dtype=latents_dtype) - sigma_conditioning = torch.tensor(sigma_conditioning, dtype=torch.float32, device=self.device) - t_conditioning = sigma_conditioning / (sigma_conditioning + 1) - - # denoiser - with self.model_memory_manager(["transformer"], low_vram=self.low_vram): - latents = self.denoise_latent_video2world( - latents, - timesteps, - text_embeddings, - negative_text_embeddings, - padding_mask, - fps, - cond_mask, - uncond_mask, - t_conditioning, - cond_indicator, - conditioning_latents, - uncond_indicator, - unconditioning_latents, - ) - - # VAE decode latent - video = self._normalize_and_decode_latents(latents, is_video2world=True) - - torch.cuda.synchronize() - e2e_toc = time.perf_counter() - - walltime_ms = (e2e_toc - e2e_tic) * 1000.0 - return self._finalize_generation( - video, - walltime_ms, - num_inference_steps, - batch_size, - warmup, - save_video, - ) - - def infer( - self, - prompt, - negative_prompt, - image_height, - image_width, - input_image=None, - input_video=None, - num_frames=1, - fps=16, - num_images_per_prompt=1, - num_videos_per_prompt=1, - sigma_conditioning=0.0001, - warmup=False, - save_output=True, - ): - """ - Run the diffusion pipeline. - - Args: - prompt (str): - The text prompt to guide image generation. - negative_prompt (str): - The prompt not to guide the image generation. Ignored when not using guidance (i.e., ignored if `guidance_scale` is - less than `1`). - input_image (image): - Input image used to initialize the latents. - input_video (video): - Input video used to initialize the latents. - image_height (int): - Height (in pixels) of the image to be generated. Must be a multiple of 8. - image_width (int): - Width (in pixels) of the image to be generated. Must be a multiple of 8. - num_frames (int): - The number of frames in the generated video. - fps (int): - The frames per second of the generated video. - num_images_per_prompt (int): - The number of images to generate per prompt. - num_videos_per_prompt (int): - The number of videos to generate per prompt. - sigma_conditioning (`float`, defaults to `0.0001`): - The sigma value used for scaling conditioning latents. Ideally, it should not be changed or should be - set to a small value close to zero. - warmup (bool): - Indicate if this is a warmup run. - save_output (bool): - Save the generated image or video (if applicable) - """ - if self.pipeline_type.is_txt2img(): - return self.generate_image( - prompt, - negative_prompt, - image_height, - image_width, - num_frames, - num_images_per_prompt, - save_output, - warmup, - ) - elif self.pipeline_type.is_video2world(): - return self.generate_video( - prompt, - negative_prompt, - image_height, - image_width, - input_image, - input_video, - num_frames, - fps, - num_videos_per_prompt, - sigma_conditioning, - save_output, - warmup, - ) - else: - raise ValueError(f"Invalid pipeline type: {self.pipeline_type}") - - def run( - self, - prompt, - negative_prompt, - height, - width, - batch_count, - num_warmup_runs, - use_cuda_graph, - **kwargs, - ): - if self.low_vram and self.use_cuda_graph: - print("[W] Using low_vram, use_cuda_graph will be disabled") - self.use_cuda_graph = False - num_warmup_runs = max(1, num_warmup_runs) if use_cuda_graph else num_warmup_runs - if num_warmup_runs > 0: - print("[I] Warming up ..") - for _ in range(num_warmup_runs): - self.infer(prompt, negative_prompt, height, width, warmup=True, **kwargs) - - outputs = [] - for _ in range(batch_count): - print("[I] Running Cosmos pipeline") - if self.nvtx_profile: - cudart.cudaProfilerStart() - output, _ = self.infer(prompt, negative_prompt, height, width, warmup=False, **kwargs) - outputs.append(output) - if self.nvtx_profile: - cudart.cudaProfilerStop() - - return outputs diff --git a/demo/Diffusion/demo_diffusion/pipeline/diffusion_pipeline.py b/demo/Diffusion/demo_diffusion/pipeline/diffusion_pipeline.py deleted file mode 100755 index 57bfc96d9..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/diffusion_pipeline.py +++ /dev/null @@ -1,997 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -from __future__ import annotations - -import abc -import argparse -import gc -import json -import os -import pathlib -import sys -from abc import ABC, abstractmethod -from typing import Any, List - -import modelopt.torch.opt as mto -import modelopt.torch.quantization as mtq -import nvtx -import torch -from cuda.bindings import runtime as cudart -from diffusers import ( - DDIMScheduler, - DDPMScheduler, - DDPMWuerstchenScheduler, - EulerAncestralDiscreteScheduler, - EulerDiscreteScheduler, - FlowMatchEulerDiscreteScheduler, - LCMScheduler, - LMSDiscreteScheduler, - PNDMScheduler, - UniPCMultistepScheduler, -) -from torch.utils.data import DataLoader - -import demo_diffusion.engine as engine_module -import demo_diffusion.image as image_module -from demo_diffusion.model import ( - make_scheduler, - merge_loras, - unload_torch_model, -) -from demo_diffusion.pipeline.calibrate import load_calib_prompts -from demo_diffusion.pipeline.model_memory_manager import ModelMemoryManager -from demo_diffusion.pipeline.type import PIPELINE_TYPE -from demo_diffusion.utils_modelopt import ( - SD_FP8_BF16_FLUX_MMDIT_BMM2_FP8_OUTPUT_CONFIG, - SD_FP8_FP16_DEFAULT_CONFIG, - SD_FP8_FP32_DEFAULT_CONFIG, - PromptImageDataset, - SameSizeSampler, - check_lora, - custom_collate, - filter_func, - filter_func_no_proj_out, - fp8_mha_disable, - generate_fp8_scales, - get_int8_config, - infinite_dataloader, - quantize_lvl, - set_fmha, - set_quant_precision, -) - - -class DiffusionPipeline(ABC): - """ - Application showcasing the acceleration of Stable Diffusion pipelines using NVidia TensorRT. - """ - VALID_DIFFUSION_PIPELINES = ( - "1.4", - "dreamshaper-7", - "xl-1.0", - "xl-turbo", - "svd-xt-1.1", - "sd3", - "3.5-medium", - "3.5-large", - "cascade", - "flux.1-dev", - "flux.1-dev-canny", - "flux.1-dev-depth", - "flux.1-schnell", - "flux.1-kontext-dev", - "wan2.2-t2v-a14b", - "cosmos-predict2-2b-text2image", - "cosmos-predict2-14b-text2image", - "cosmos-predict2-2b-video2world", - "cosmos-predict2-14b-video2world", - ) - SCHEDULER_DEFAULTS = { - "1.4": "PNDM", - "dreamshaper-7": "PNDM", - "xl-1.0": "Euler", - "xl-turbo": "EulerA", - "3.5-large": "FlowMatchEuler", - "3.5-medium": "FlowMatchEuler", - "svd-xt-1.1": "Euler", - "cascade": "DDPMWuerstchen", - "flux.1-dev": "FlowMatchEuler", - "flux.1-dev-canny": "FlowMatchEuler", - "flux.1-dev-depth": "FlowMatchEuler", - "flux.1-schnell": "FlowMatchEuler", - "flux.1-kontext-dev": "FlowMatchEuler", - "wan2.2-t2v-a14b": "UniPC", - "cosmos-predict2-2b-text2image": "FlowMatchEuler", - "cosmos-predict2-14b-text2image": "FlowMatchEuler", - "cosmos-predict2-2b-video2world": "FlowMatchEuler", - "cosmos-predict2-14b-video2world": "FlowMatchEuler", - } - - def __init__( - self, - dd_path, - version="1.4", - pipeline_type=PIPELINE_TYPE.TXT2IMG, - bf16=False, - max_batch_size=16, - denoising_steps=30, - scheduler=None, - device="cuda", - output_dir=".", - hf_token=None, - verbose=False, - nvtx_profile=False, - use_cuda_graph=False, - framework_model_dir="pytorch_model", - return_latents=False, - low_vram=False, - torch_inference="", - torch_fallback=None, - weight_streaming=False, - text_encoder_weight_streaming_budget_percentage=None, - denoiser_weight_streaming_budget_percentage=None, - controlnet=None, - ): - """ - Initializes the Diffusion pipeline. - - Args: - dd_path (load_module.DDPath): DDPath object that contains all paths used in DemoDiffusion. - version (str): - The version of the pipeline. Should be one of the values listed in DiffusionPipeline.VALID_DIFFUSION_PIPELINES. - pipeline_type (PIPELINE_TYPE): - Task performed by the current pipeline. Should be one of PIPELINE_TYPE.__members__. - max_batch_size (int): - Maximum batch size for dynamic batch engine. - bf16 (`bool`, defaults to False): - Whether to run the pipeline in BFloat16 precision. - denoising_steps (int): - The number of denoising steps. - More denoising steps usually lead to a higher quality image at the expense of slower inference. - scheduler (str): - The scheduler to guide the denoising process. Must be one of the values listed in DiffusionPipeline.SCHEDULER_DEFAULTS.values(). - device (str): - PyTorch device to run inference. Default: 'cuda'. - output_dir (str): - Output directory for log files and image artifacts. - hf_token (str): - HuggingFace User Access Token to use for downloading Stable Diffusion model checkpoints. - verbose (bool): - Enable verbose logging. - nvtx_profile (bool): - Insert NVTX profiling markers. - use_cuda_graph (bool): - Use CUDA graph to capture engine execution and then launch inference. - framework_model_dir (str): - cache directory for framework checkpoints. - return_latents (bool): - Skip decoding the image and return latents instead. - low_vram (bool): - [FLUX only] Optimize for low VRAM usage, possibly at the expense of inference performance. Disabled by default. - torch_inference (str): - Run inference with PyTorch (using specified compilation mode) instead of TensorRT. The compilation mode specified should be one of ['eager', 'reduce-overhead', 'max-autotune']. - torch_fallback (str): - [FLUX only] Comma separated list of models to be inferenced using PyTorch instead of TRT. For example --torch-fallback t5,transformer. If --torch-inference set, this parameter will be ignored. - weight_streaming (`bool`, defaults to False): - Whether to enable weight streaming during TensorRT engine build. - text_encoder_ws_budget_percentage (`int`, defaults to None): - Weight streaming budget as a percentage of the size of total streamable weights for the text encoder model. - denoiser_weight_streaming_budget_percentage (`int`, defaults to None): - Weight streaming budget as a percentage of the size of total streamable weights for the denoiser model. - controlnet (str, defaults to None): - Type of ControlNet to use for the pipeline. - """ - self.bf16 = bf16 - self.dd_path = dd_path - - self.denoising_steps = denoising_steps - self.max_batch_size = max_batch_size - - self.framework_model_dir = framework_model_dir - self.output_dir = output_dir - for directory in [self.framework_model_dir, self.output_dir]: - if not os.path.exists(directory): - print(f"[I] Create directory: {directory}") - pathlib.Path(directory).mkdir(parents=True) - - self.hf_token = hf_token - self.device = device - self.verbose = verbose - self.nvtx_profile = nvtx_profile - - self.version = version - self.pipeline_type = pipeline_type - self.return_latents = return_latents - - self.low_vram = low_vram - self.weight_streaming = weight_streaming - self.text_encoder_weight_streaming_budget_percentage = text_encoder_weight_streaming_budget_percentage - self.denoiser_weight_streaming_budget_percentage = denoiser_weight_streaming_budget_percentage - - self.stages = self.get_model_names(self.pipeline_type, controlnet) - # config to store additional info - self.config = {} - if torch_fallback: - assert type(torch_fallback) is list - for model_name in torch_fallback: - if model_name not in self.stages: - raise ValueError(f'Model "{model_name}" set in --torch-fallback does not exist') - self.config[model_name.replace("-", "_") + "_torch_fallback"] = True - print(f"[I] Setting torch_fallback for {model_name} model.") - - if not scheduler: - scheduler = 'UniPC' if self.pipeline_type.is_controlnet() and not self.version == "3.5-large" else self.SCHEDULER_DEFAULTS.get(version, 'DDIM') - print(f"[I] Autoselected scheduler: {scheduler}") - - scheduler_class_map = { - "DDIM" : DDIMScheduler, - "DDPM" : DDPMScheduler, - "EulerA" : EulerAncestralDiscreteScheduler, - "Euler" : EulerDiscreteScheduler, - "LCM" : LCMScheduler, - "LMSD" : LMSDiscreteScheduler, - "PNDM" : PNDMScheduler, - "UniPC" : UniPCMultistepScheduler, - "DDPMWuerstchen" : DDPMWuerstchenScheduler, - "FlowMatchEuler": FlowMatchEulerDiscreteScheduler, - } - try: - scheduler_class = scheduler_class_map[scheduler] - except KeyError: - raise ValueError( - f"Unsupported scheduler {scheduler}. Should be one of {list(scheduler_class_map.keys())}." - ) - self.scheduler = make_scheduler(scheduler_class, version, pipeline_type, hf_token, framework_model_dir) - - self.torch_inference = torch_inference - if self.torch_inference: - torch._inductor.config.conv_1x1_as_mm = True - torch._inductor.config.coordinate_descent_tuning = True - torch._inductor.config.epilogue_fusion = False - torch._inductor.config.coordinate_descent_check_all_directions = True - self.use_cuda_graph = use_cuda_graph - - # initialized in load_engines() - self.models = {} - self.torch_models = {} - self.engine = {} - self.shape_dicts = {} - self.shared_device_memory = None - self.lora_loader = None - - # initialized in load_resources() - self.events = {} - self.generator = None - self.markers = {} - self.seed = None - self.stream = None - self.tokenizer = None - - def model_memory_manager(self, model_names, low_vram=False): - return ModelMemoryManager(self, model_names, low_vram) - - @classmethod - @abc.abstractmethod - def FromArgs(cls, args: argparse.Namespace, pipeline_type: PIPELINE_TYPE) -> DiffusionPipeline: - """Factory method to construct a concrete pipeline object from parsed arguments.""" - raise NotImplementedError("FromArgs cannot be called from the abstract base class.") - - @classmethod - @abc.abstractmethod - def get_model_names(cls, pipeline_type: PIPELINE_TYPE, controlnet_type: str = None) -> List[str]: - """Return a list of model names used by this pipeline.""" - raise NotImplementedError("get_model_names cannot be called from the abstract base class.") - - @classmethod - def _get_pipeline_uid(cls, version: str) -> str: - """Return the unique ID of this pipeline. - - This is typically used to determine the default path for things like engine files, artifacts caches, etc. - """ - return f"{cls.__name__}_{version}" - - def profile_start(self, name, color="blue", domain=None): - if self.nvtx_profile: - self.markers[name] = nvtx.start_range(message=name, color=color, domain=domain) - if name in self.events: - cudart.cudaEventRecord(self.events[name][0], 0) - - def profile_stop(self, name): - if name in self.events: - cudart.cudaEventRecord(self.events[name][1], 0) - if self.nvtx_profile: - nvtx.end_range(self.markers[name]) - - def load_resources(self, image_height, image_width, batch_size, seed): - # Initialize noise generator - if seed is not None: - self.seed = seed - self.generator = torch.Generator(device="cuda").manual_seed(seed) - - # Create CUDA events and stream - for stage in self.stages: - self.events[stage] = [cudart.cudaEventCreate()[1], cudart.cudaEventCreate()[1]] - self.stream = cudart.cudaStreamCreate()[1] - - # Allocate TensorRT I/O buffers - if not self.torch_inference: - for model_name, obj in self.models.items(): - if self.torch_fallback[model_name]: - continue - shape_dict = obj.get_shape_dict( - batch_size, image_height, image_width, - **({'num_frames': obj.num_frames} if hasattr(obj, 'num_frames') and obj.num_frames else {}) - ) - - self.shape_dicts[model_name] = shape_dict - if not self.low_vram: - self.engine[model_name].allocate_buffers(shape_dict=shape_dict, device=self.device) - - @abstractmethod - def _initialize_models(self, *args, **kwargs): - raise NotImplementedError("Please Implement the _initialize_models method") - - def _prepare_model_configs( - self, - enable_refit, - int8, - fp8, - fp4 - ): - model_names = self.models.keys() - self.torch_fallback = dict(zip(model_names, [self.torch_inference or self.config.get(model_name.replace('-','_')+'_torch_fallback', False) for model_name in model_names])) - - configs = {} - for model_name in model_names: - # Initialize config - do_engine_refit = enable_refit and not self.pipeline_type.is_sd_xl_refiner() and any(model_name.startswith(prefix) for prefix in ("unet", "transformer")) - do_lora_merge = not enable_refit and self.lora_loader and any(model_name.startswith(prefix) for prefix in ("unet", "transformer")) - - config = { - "do_engine_refit": do_engine_refit, - "do_lora_merge": do_lora_merge, - "use_int8": False, - "use_fp8": False, - 'use_fp4': False, - } - - # TODO: Move this to when arguments are first being validated in dd_argparse.py - # 8-bit/4-bit precision inference - if int8: - assert self.pipeline_type.is_sd_xl_base() or self.version in [ - "1.4", - ], "int8 quantization only supported for SDXL and SD1.4 pipeline" - if (self.pipeline_type.is_sd_xl() and model_name == "unetxl") or (model_name == "unet"): - config["use_int8"] = True - - elif fp8: - assert ( - self.pipeline_type.is_sd_xl() - or self.version in ["1.4"] - or self.version.startswith("flux.1") - or self.version.startswith("3.5-large") - ), "fp8 quantization only supported for SDXL, SD1.4, SD3.5-large and FLUX pipelines" - if ( - (self.pipeline_type.is_sd_xl() and model_name == "unetxl") - or (self.version.startswith("flux.1") and model_name == "transformer") - or ( - self.version.startswith("3.5-large") - and ("transformer" in model_name or "controlnet" in model_name) - ) - or (model_name == "unet") - ): - config["use_fp8"] = True - elif fp4: - config['use_fp4'] = True - - # Setup paths - config["onnx_path"] = self.dd_path.model_name_to_unoptimized_onnx_path[model_name] - config["onnx_opt_path"] = self.dd_path.model_name_to_optimized_onnx_path[model_name] - config["engine_path"] = self.dd_path.model_name_to_engine_path[model_name] - config["weights_map_path"] = ( - self.dd_path.model_name_to_weights_map_path[model_name] if config["do_engine_refit"] else None - ) - config["state_dict_path"] = self.dd_path.model_name_to_quantized_model_state_dict_path[model_name] - config["refit_weights_path"] = self.dd_path.model_name_to_refit_weights_path[model_name] - - configs[model_name] = config - - return configs - - def _calibrate_and_save_model( - self, - pipeline, - model, - model_config, - quantization_level, - quantization_percentile, - quantization_alpha, - calibration_size, - calib_batch_size, - enable_lora_merge = False, - **kwargs): - print(f"[I] Calibrated weights not found, generating {model_config['state_dict_path']}") - - # TODO check size > calibration_size - def do_calibrate(pipeline, calibration_prompts, **kwargs): - for i_th, prompts in enumerate(calibration_prompts): - if i_th >= kwargs["calib_size"]: - return - if kwargs["model_id"] in ("flux.1-dev", "flux.1-schnell"): - common_args = { - "prompt": prompts, - "prompt_2": prompts, - "num_inference_steps": kwargs["n_steps"], - "height": kwargs.get("height", 1024), - "width": kwargs.get("width", 1024), - "guidance_scale": 3.5, - "max_sequence_length": 512 if kwargs["model_id"] == "flux.1-dev" else 256, - } - else: - common_args = { - "prompt": prompts, - "num_inference_steps": kwargs["n_steps"], - "negative_prompt": ["normal quality, low quality, worst quality, low res, blurry, nsfw, nude"] - * len(prompts), - } - - pipeline(**common_args).images - - def do_calibrate_img2img(pipeline, dataloader, **kwargs): - for i_th, (img_conds, prompts) in enumerate(dataloader): - if i_th >= kwargs["calib_size"]: - return - - common_args = { - "prompt": list(prompts), - "control_image": img_conds, - "num_inference_steps": kwargs["n_steps"], - "height": img_conds.size(2), - "width": img_conds.size(3), - "generator": torch.Generator().manual_seed(42), - "guidance_scale": 3.5, - "max_sequence_length": 512, - } - pipeline(**common_args).images - - if self.version in ("flux.1-dev-depth", "flux.1-dev-canny"): - dataset = PromptImageDataset( - root_dir=self.calibration_dataset, - ) - - dataloader = DataLoader( - dataset, - batch_size=calib_batch_size, - shuffle=False, - num_workers=0, - sampler=SameSizeSampler(dataset=dataset, batch_size=calib_batch_size), - collate_fn=custom_collate, - ) - else: - root_dir = os.path.dirname(os.path.abspath(sys.modules["__main__"].__file__)) - calibration_file = os.path.join(root_dir, "calibration_data", "calibration-prompts.txt") - calibration_prompts = load_calib_prompts(calib_batch_size, calibration_file) - - def forward_loop(model): - if self.version not in ("sd3", "flux.1-dev", "flux.1-schnell", "flux.1-dev-depth", "flux.1-dev-canny"): - pipeline.unet = model - else: - pipeline.transformer = model - - if self.version in ("flux.1-dev-depth", "flux.1-dev-canny"): - do_calibrate_img2img( - pipeline=pipeline, - dataloader=infinite_dataloader(dataloader), - calib_size=calibration_size // calib_batch_size, - n_steps=self.denoising_steps, - model_id=self.version, - ) - else: - do_calibrate( - pipeline=pipeline, - calibration_prompts=calibration_prompts, - calib_size=calibration_size // calib_batch_size, - n_steps=self.denoising_steps, - model_id=self.version, - **kwargs - ) - - print(f"[I] Performing calibration for {calibration_size} steps.") - if model_config['use_int8']: - quant_config = get_int8_config( - model, - quantization_level, - quantization_alpha, - quantization_percentile, - self.denoising_steps - ) - elif model_config['use_fp8']: - if self.version.startswith("flux.1"): - quant_config = SD_FP8_BF16_FLUX_MMDIT_BMM2_FP8_OUTPUT_CONFIG - else: - quant_config = SD_FP8_FP16_DEFAULT_CONFIG - - # Handle LoRA - if enable_lora_merge: - assert self.lora_loader is not None - model = merge_loras(model, self.lora_loader) - - check_lora(model) - - if self.version.startswith("flux.1"): - set_quant_precision(quant_config, "BFloat16") - mtq.quantize(model, quant_config, forward_loop) - mto.save(model, model_config['state_dict_path']) - - def _get_quantized_model( - self, - obj, - model_config, - quantization_level, - quantization_percentile, - quantization_alpha, - calibration_size, - calib_batch_size, - enable_lora_merge = False, - **kwargs): - pipeline = obj.get_pipeline() - is_flux = self.version.startswith("flux.1") - model = pipeline.unet if self.version not in ("sd3", "flux.1-dev", "flux.1-schnell", "flux.1-dev-depth", "flux.1-dev-canny") else pipeline.transformer - if model_config['use_fp8'] and quantization_level == 4.0: - set_fmha(model, is_flux=is_flux) - - if not os.path.exists(model_config['state_dict_path']): - self._calibrate_and_save_model( - pipeline, - model, - model_config, - quantization_level, - quantization_percentile, - quantization_alpha, - calibration_size, - calib_batch_size, - enable_lora_merge, - **kwargs) - else: - mto.restore(model, model_config['state_dict_path']) - - if not os.path.exists(model_config['onnx_path']): - quantize_lvl(self.version, model, quantization_level) - if self.version.startswith("flux.1"): - mtq.disable_quantizer(model, filter_func_no_proj_out) - else: - mtq.disable_quantizer(model, filter_func) - if model_config['use_fp8'] and not self.version.startswith("flux.1"): - generate_fp8_scales(model) - if quantization_level == 4.0: - fp8_mha_disable(model, quantized_mha_output=False) # Remove Q/DQ after BMM2 in MHA - else: - model = None - - return model - - @abstractmethod - def download_onnx_models(self, model_name: str, model_config: dict[str, Any]) -> None: - """Download pre-exported ONNX Models""" - raise NotImplementedError("Please Implement the download_onnx_models method") - - def is_native_export_supported(self, model_config: dict[str, Any]) -> bool: - """Check if pipeline supports native ONNX export""" - # Native export is supported by default - return True - - @staticmethod - def _fix_bf16_resize_nodes(onnx_opt_path): - """Cast Resize node I/O for strongly-typed TRT engine builds. - TRT does not support BF16 for the Resize operator, so inputs are - cast to FP32 and outputs are cast back to BF16.""" - import onnx - import onnx_graphsurgeon as gs - from demo_diffusion.model import load - from demo_diffusion.utils_modelopt import cast_resize_io - - onnx_graph = onnx.load(onnx_opt_path, load_external_data=True) - graph = gs.import_onnx(onnx_graph) - - resize_nodes = [n for n in graph.nodes if n.op == "Resize"] - if not resize_nodes: - return - - print(f"[I] Fixing {len(resize_nodes)} BF16 Resize node(s) in downloaded model: {onnx_opt_path}") - cast_resize_io(graph, output_dtype=onnx.TensorProto.BFLOAT16) - graph.cleanup().toposort() - onnx_graph = gs.export_onnx(graph) - - if load.onnx_graph_needs_external_data(onnx_graph): - onnx.save_model( - onnx_graph, - onnx_opt_path, - save_as_external_data=True, - all_tensors_to_one_file=True, - convert_attribute=False, - ) - else: - onnx.save(onnx_graph, onnx_opt_path) - - def _export_onnx( - self, - obj, - model_name, - model_config, - opt_image_height, - opt_image_width, - static_shape, - onnx_opset, - quantization_level, - quantization_percentile, - quantization_alpha, - calibration_size, - calib_batch_size, - onnx_export_only, - download_onnx_models, - ): - # With onnx_export_only True, the export still happens even if the TRT engine exists. However, it will not re-run the export if the onnx exists. - do_export_onnx = (not os.path.exists(model_config['engine_path']) or onnx_export_only) and not os.path.exists(model_config['onnx_opt_path']) - do_export_weights_map = model_config['weights_map_path'] and not os.path.exists(model_config['weights_map_path']) - - # If ONNX export is required, either download ONNX models or check if the pipeline supports native ONNX export - if do_export_onnx: - if download_onnx_models: - self.download_onnx_models(model_name, model_config) - # Fix Resize nodes for strongly-typed TRT builds. - # Downloaded models bypass optimize(), so apply the fix here. - if obj.bf16: - self._fix_bf16_resize_nodes(model_config['onnx_opt_path']) - do_export_onnx = False - else: - self.is_native_export_supported(model_config) - - dynamo = True if (self.pipeline_type.is_video2world() and model_name == "transformer") or (self.pipeline_type.is_txt2vid() and (model_name in ["transformer", "transformer_2"])) or (self.version.startswith("flux.1") and model_name == "transformer" and obj.fp16) else False - - export_kwargs = { - "static_shape": static_shape, - "dynamo": dynamo, - **({'opt_num_frames': obj.num_frames} if hasattr(obj, 'num_frames') and obj.num_frames else {}) - } - - if do_export_onnx or do_export_weights_map: - if not model_config['use_int8'] and not model_config['use_fp8']: - obj.export_onnx( - model_config["onnx_path"], - model_config["onnx_opt_path"], - onnx_opset, - opt_image_height, - opt_image_width, - enable_lora_merge=model_config["do_lora_merge"], - lora_loader=self.lora_loader, - **export_kwargs, - ) - else: - print(f"[I] Generating quantized ONNX model: {model_config['onnx_path']}") - quantized_model = self._get_quantized_model( - obj, - model_config, - quantization_level, - quantization_percentile, - quantization_alpha, - calibration_size, - calib_batch_size, - height=opt_image_width, - width=opt_image_width, - enable_lora_merge=model_config["do_lora_merge"], - ) - obj.export_onnx( - model_config["onnx_path"], - model_config["onnx_opt_path"], - onnx_opset, - opt_image_height, - opt_image_width, - custom_model=quantized_model, - **export_kwargs, - ) - - # FIXME do_export_weights_map needs ONNX graph - if do_export_weights_map: - print(f"[I] Saving weights map: {model_config['weights_map_path']}") - obj.export_weights_map(model_config['onnx_opt_path'], model_config['weights_map_path']) - - def _build_engine(self, obj, engine, model_config, opt_batch_size, opt_image_height, opt_image_width, optimization_level, static_batch, static_shape, enable_all_tactics, timing_cache): - update_output_names = obj.get_output_names() + obj.extra_output_names if obj.extra_output_names else None - tf32amp = obj.tf32 - weight_streaming = getattr(obj, 'weight_streaming', False) - precision_constraints = 'none' - input_profile = obj.get_input_profile( - opt_batch_size, opt_image_height, opt_image_width, - static_batch=static_batch, static_shape=static_shape, - **({'num_frames': obj.num_frames} if hasattr(obj, 'num_frames') and obj.num_frames else {}) - ) - - engine.build( - model_config["onnx_opt_path"], - tf32=tf32amp, - input_profile=input_profile, - enable_refit=model_config["do_engine_refit"], - enable_all_tactics=enable_all_tactics, - timing_cache=timing_cache, - update_output_names=update_output_names, - weight_streaming=weight_streaming, - verbose=self.verbose, - builder_optimization_level=optimization_level, - precision_constraints=precision_constraints, - ) - - def _refit_engine(self, obj, model_name, model_config): - assert model_config['weights_map_path'] - with open(model_config['weights_map_path'], 'r') as fp_wts: - print(f"[I] Loading weights map: {model_config['weights_map_path']} ") - [weights_name_mapping, weights_shape_mapping] = json.load(fp_wts) - - if not os.path.exists(model_config['refit_weights_path']): - model = merge_loras(obj.get_model(), self.lora_loader) - refit_weights, updated_weight_names = engine_module.get_refit_weights( - model.state_dict(), model_config["onnx_opt_path"], weights_name_mapping, weights_shape_mapping - ) - print(f"[I] Saving refit weights: {model_config['refit_weights_path']}") - torch.save((refit_weights, updated_weight_names), model_config["refit_weights_path"]) - unload_torch_model(model) - else: - print(f"[I] Loading refit weights: {model_config['refit_weights_path']}") - refit_weights, updated_weight_names = torch.load(model_config['refit_weights_path']) - self.engine[model_name].refit(refit_weights, updated_weight_names) - - def _load_torch_models(self): - # Load torch models - for model_name, obj in self.models.items(): - if self.torch_fallback[model_name]: - self.torch_models[model_name] = obj.get_model(torch_inference=self.torch_inference) - if self.low_vram: - self.torch_models[model_name] = self.torch_models[model_name].to('cpu') - torch.cuda.empty_cache() - - def load_engines( - self, - framework_model_dir, - onnx_opset, - opt_batch_size, - opt_image_height, - opt_image_width, - optimization_level=3, - static_batch=False, - static_shape=True, - enable_refit=False, - enable_all_tactics=False, - timing_cache=None, - int8=False, - fp8=False, - fp4=False, - quantization_level=2.5, - quantization_percentile=1.0, - quantization_alpha=0.8, - calibration_size=32, - calib_batch_size=2, - onnx_export_only=False, - download_onnx_models=False, - ): - """ - Build and load engines for TensorRT accelerated inference. - Export ONNX models first, if applicable. - - Args: - framework_model_dir (str): - Directory to store the framework model ckpt. - onnx_opset (int): - ONNX opset version to export the models. - opt_batch_size (int): - Batch size to optimize for during engine building. - opt_image_height (int): - Image height to optimize for during engine building. Must be a multiple of 8. - opt_image_width (int): - Image width to optimize for during engine building. Must be a multiple of 8. - optimization_level (int): - Optimization level to build the TensorRT engine with. - static_batch (bool): - Build engine only for specified opt_batch_size. - static_shape (bool): - Build engine only for specified opt_image_height & opt_image_width. Default = True. - enable_refit (bool): - Build engines with refit option enabled. - enable_all_tactics (bool): - Enable all tactic sources during TensorRT engine builds. - timing_cache (str): - Path to the timing cache to speed up TensorRT build. - int8 (bool): - Whether to quantize to int8 format or not (SDXL, SD15 and SD21 only). - fp8 (bool): - Whether to quantize to fp8 format or not (SDXL, SD15 and SD21 only). - quantization_level (float): - Controls which layers to quantize. 1: CNN, 2: CNN+FFN, 2.5: CNN+FFN+QKV, 3: CNN+FC - quantization_percentile (float): - Control quantization scaling factors (amax) collecting range, where the minimum amax in - range(n_steps * percentile) will be collected. Recommendation: 1.0 - quantization_alpha (float): - The alpha parameter for SmoothQuant quantization used for linear layers. - Recommendation: 0.8 for SDXL - calibration_size (int): - The number of steps to use for calibrating the model for quantization. - Recommendation: 32, 64, 128 for SDXL - calib_batch_size (int): - The batch size to use for calibration. Defaults to 2. - onnx_export_only (bool): - Whether only export onnx without building the TRT engine. - download_onnx_models (bool): - Download pre-exported ONNX models - """ - - self._initialize_models(framework_model_dir, int8, fp8, fp4) - - model_configs = self._prepare_model_configs(enable_refit, int8, fp8, fp4) - - # Export models to ONNX - for model_name, obj in self.models.items(): - if self.torch_fallback[model_name]: - continue - self._export_onnx( - obj, - model_name, - model_configs[model_name], - opt_image_height, - opt_image_width, - static_shape, - onnx_opset, - quantization_level, - quantization_percentile, - quantization_alpha, - calibration_size, - calib_batch_size, - onnx_export_only, - download_onnx_models, - ) - - # Release temp GPU memory during onnx export to avoid OOM. - gc.collect() - torch.cuda.empty_cache() - - if onnx_export_only: - return - - # Build TensorRT engines - for model_name, obj in self.models.items(): - if self.torch_fallback[model_name]: - continue - - model_config = model_configs[model_name] - engine = engine_module.Engine(model_config["engine_path"]) - if not os.path.exists(model_config['engine_path']): - self._build_engine(obj, engine, model_config, opt_batch_size, opt_image_height, opt_image_width, optimization_level, static_batch, static_shape, enable_all_tactics, timing_cache) - self.engine[model_name] = engine - - # Load and refit TensorRT engines - for model_name, obj in self.models.items(): - if self.torch_fallback[model_name]: - continue - model_config = model_configs[model_name] - - # For non low_vram case, the engines will remain in GPU memory from now on. - assert self.engine[model_name].engine is None - if not self.low_vram: - weight_streaming = getattr(obj, 'weight_streaming', False) - weight_streaming_budget_percentage = getattr(obj, 'weight_streaming_budget_percentage', None) - self.engine[model_name].load(weight_streaming, weight_streaming_budget_percentage) - - if model_config['do_engine_refit'] and self.lora_loader: - # For low_vram, using on-demand load and unload for refit. - if self.low_vram: - assert self.engine[model_name].engine is None - self.engine[model_name].load() - self._refit_engine(obj, model_name, model_config) - if self.low_vram: - self.engine[model_name].unload() - - # Load PyTorch models if torch-inference mode is enabled - self._load_torch_models() - - # Reclaim GPU memory from torch cache - torch.cuda.empty_cache() - - def calculate_max_device_memory(self): - max_device_memory = 0 - for model_name, engine in self.engine.items(): - if self.low_vram: - engine.load() - max_device_memory = max(max_device_memory, engine.engine.device_memory_size_v2) - if self.low_vram: - engine.unload() - return max_device_memory - - def get_device_memory_sizes(self): - device_memory_sizes = {} - for model_name, engine in self.engine.items(): - engine.load() - device_memory_sizes[model_name] = engine.engine.device_memory_size_v2 - engine.unload() - return device_memory_sizes - - def activate_engines(self, shared_device_memory=None): - if shared_device_memory is None: - max_device_memory = self.calculate_max_device_memory() - _, shared_device_memory = cudart.cudaMalloc(max_device_memory) - self.shared_device_memory = shared_device_memory - # Load and activate TensorRT engines - if not self.low_vram: - for engine in self.engine.values(): - engine.activate(device_memory=self.shared_device_memory) - - def run_engine(self, model_name, feed_dict): - engine = self.engine[model_name] - # CUDA graphs should be disabled when low_vram is enabled. - if self.low_vram: - assert self.use_cuda_graph == False - return engine.infer(feed_dict, self.stream, use_cuda_graph=self.use_cuda_graph) - - def teardown(self): - for e in self.events.values(): - cudart.cudaEventDestroy(e[0]) - cudart.cudaEventDestroy(e[1]) - - for engine in self.engine.values(): - engine.deallocate_buffers() - engine.deactivate() - engine.unload(verbose=False) - del engine - - if self.shared_device_memory: - cudart.cudaFree(self.shared_device_memory) - - for torch_model in self.torch_models.values(): - torch_model.to("cpu") - del torch_model - - cudart.cudaStreamDestroy(self.stream) - del self.stream - - gc.collect() - torch.cuda.empty_cache() - - def initialize_latents(self, batch_size, unet_channels, latent_height, latent_width, latents_dtype=torch.float32): - latents_shape = (batch_size, unet_channels, latent_height, latent_width) - latents = torch.randn(latents_shape, device=self.device, dtype=latents_dtype, generator=self.generator) - # Scale the initial noise by the standard deviation required by the scheduler - latents = latents * self.scheduler.init_noise_sigma - return latents - - def save_image(self, images, pipeline, prompt, seed): - # Save image - prompt_prefix = ''.join(set([prompt[i].replace(' ','_')[:10] for i in range(len(prompt))])) - image_name_prefix = '-'.join([pipeline, prompt_prefix, str(seed)]) - image_name_suffix = 'torch' if self.torch_inference else 'trt' - image_module.save_image(images, self.output_dir, image_name_prefix, image_name_suffix) - - @abstractmethod - def print_summary(self): - """Print a summary of the pipeline's configuration.""" - raise NotImplementedError("Please Implement the print_summary method") - - @abstractmethod - def infer(self): - """Perform inference using the pipeline.""" - raise NotImplementedError("Please Implement the infer method") - - @abstractmethod - def run(self): - """Run the pipeline.""" - raise NotImplementedError("Please Implement the run method") diff --git a/demo/Diffusion/demo_diffusion/pipeline/flux_pipeline.py b/demo/Diffusion/demo_diffusion/pipeline/flux_pipeline.py deleted file mode 100644 index 346766a8e..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/flux_pipeline.py +++ /dev/null @@ -1,1392 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -import argparse -import inspect -import os -import time -import warnings -from typing import Any, List, Optional - -import numpy as np -import tensorrt as trt -import torch -from cuda.bindings import runtime as cudart -from diffusers.image_processor import VaeImageProcessor -from flux.content_filters import PixtralContentFilter -from huggingface_hub import snapshot_download - -from demo_diffusion import path as path_module -from demo_diffusion.model import ( - CLIPModel, - FLUXLoraLoader, - FluxTransformerModel, - T5Model, - VAEEncoderModel, - VAEModel, - get_clip_embedding_dim, - load, - make_tokenizer, -) -from demo_diffusion.pipeline.diffusion_pipeline import DiffusionPipeline -from demo_diffusion.pipeline.type import PIPELINE_TYPE - -TRT_LOGGER = trt.Logger(trt.Logger.ERROR) - -PREFERRED_KONTEXT_RESOLUTIONS = [ - (672, 1568), - (688, 1504), - (720, 1456), - (752, 1392), - (800, 1328), - (832, 1248), - (880, 1184), - (944, 1104), - (1024, 1024), - (1104, 944), - (1184, 880), - (1248, 832), - (1328, 800), - (1392, 752), - (1456, 720), - (1504, 688), - (1568, 672), -] - - -class FluxKontextUtil: - """ - Utility class for Flux Kontext-related operations including context dimension calculations - and resolution handling. - """ - - @staticmethod - def _get_context_dim( - image_height: int, - image_width: int, - compression_factor: int, - ) -> int: - """ - Calculate the context dimension based on image dimensions and compression factor. - - Args: - image_height: Height of the image - image_width: Width of the image - compression_factor: Compression factor applied to the image - - Returns: - The calculated sequence length for the context - """ - seq_len = (image_height // (2 * compression_factor)) * (image_width // (2 * compression_factor)) - return seq_len - - @staticmethod - def get_context_latent_dim( - version: str, - kontext_resolution: tuple = None, - compression_factor: int = 8, - static_shape: bool = False, - ): - """ - Get the context latent dimensions for Flux Kontext models. - - Args: - version: Model version string - kontext_resolution: Tuple of (width, height) for kontext resolution - compression_factor: Compression factor for the model - static_shape: Whether to use static shapes - - Returns: - Tuple of (min_context_latent_dim, context_latent_dim, max_context_latent_dim) - """ - min_context_latent_dim, context_latent_dim, max_context_latent_dim = 0, 0, 0 - - if version == "flux.1-kontext-dev": - assert kontext_resolution is not None, "kontext_resolution must be provided for flux.1-kontext-dev" - - # get opt context size - context_latent_dim = FluxKontextUtil._get_context_dim( - image_height=kontext_resolution[1], - image_width=kontext_resolution[0], - compression_factor=compression_factor, - ) - - # get min context size - _, min_context_width, min_context_height = min((w * h, w, h) for w, h in PREFERRED_KONTEXT_RESOLUTIONS) - min_context_latent_dim = ( - context_latent_dim - if static_shape - else FluxKontextUtil._get_context_dim( - image_height=min_context_height, - image_width=min_context_width, - compression_factor=compression_factor, - ) - ) - - # get max context size - _, max_context_width, max_context_height = max((w * h, w, h) for w, h in PREFERRED_KONTEXT_RESOLUTIONS) - max_context_latent_dim = ( - context_latent_dim - if static_shape - else FluxKontextUtil._get_context_dim( - image_height=max_context_height, - image_width=max_context_width, - compression_factor=compression_factor, - ) - ) - - return min_context_latent_dim, context_latent_dim, max_context_latent_dim - - @staticmethod - def get_preferred_resolutions(): - """ - Get the list of preferred Kontext resolutions. - - Returns: - List of (width, height) tuples representing preferred resolutions - """ - return PREFERRED_KONTEXT_RESOLUTIONS.copy() - - @staticmethod - def get_min_max_kontext_dimensions(): - """ - Get the resolution tuples with minimum and maximum aspect ratios from preferred Kontext resolutions. - - Returns: - Tuple of ((min_aspect_width, min_aspect_height), (max_aspect_width, max_aspect_height)) - """ - widths = [w for w, h in PREFERRED_KONTEXT_RESOLUTIONS] - heights = [h for w, h in PREFERRED_KONTEXT_RESOLUTIONS] - - min_width = min(widths) - max_width = max(widths) - min_height = min(heights) - max_height = max(heights) - - return (min_width, min_height), (max_width, max_height) - -def calculate_shift( - image_seq_len, - base_seq_len: int = 256, - max_seq_len: int = 4096, - base_shift: float = 0.5, - max_shift: float = 1.16, -): - m = (max_shift - base_shift) / (max_seq_len - base_seq_len) - b = base_shift - m * base_seq_len - mu = image_seq_len * m + b - return mu - - -class FluxPipeline(DiffusionPipeline): - """ - Application showcasing the acceleration of Flux pipelines using Nvidia TensorRT. - """ - - def __init__( - self, - version="flux.1-dev", - pipeline_type=PIPELINE_TYPE.TXT2IMG, - guidance_scale=3.5, - max_sequence_length=512, - calibration_dataset=None, - t5_weight_streaming_budget_percentage=None, - transformer_weight_streaming_budget_percentage=None, - lora_scale: float = 1.0, - lora_weight: Optional[List[float]] = None, - lora_path: Optional[List[str]] = None, - **kwargs, - ): - """ - Initializes the Flux pipeline. - - Args: - version (`str`, defaults to `flux.1-dev`) - Version of the underlying Flux model. - guidance_scale (`float`, defaults to 3.5): - Guidance scale is enabled by setting as > 1. - Higher guidance scale encourages to generate images that are closely linked to the text prompt, usually at the expense of lower image quality. - max_sequence_length (`int`, defaults to 512): - Maximum sequence length to use with the `prompt`. - t5_weight_streaming_budget_percentage (`int`, defaults to None): - Weight streaming budget as a percentage of the size of total streamable weights for the T5 model. - transformer_weight_streaming_budget_percentage (`int`, defaults to None): - Weight streaming budget as a percentage of the size of total streamable weights for the transformer model. - """ - super().__init__( - version=version, - pipeline_type=pipeline_type, - text_encoder_weight_streaming_budget_percentage=t5_weight_streaming_budget_percentage, - denoiser_weight_streaming_budget_percentage=transformer_weight_streaming_budget_percentage, - **kwargs, - ) - self.guidance_scale = guidance_scale - self.max_sequence_length = max_sequence_length - self.calibration_dataset = calibration_dataset # Currently supported for Flux ControlNet pipelines only - - # Initialize LoRA - self.lora_loader = None - if lora_path: - self.lora_weights = dict() - self.lora_loader = FLUXLoraLoader(lora_path, lora_weight, lora_scale) - assert len(lora_path) == len(lora_weight) - for i, path in enumerate(lora_path): - self.lora_weights[path] = lora_weight[i] - - @classmethod - def FromArgs(cls, args: argparse.Namespace, pipeline_type: PIPELINE_TYPE) -> FluxPipeline: - """Factory method to construct a `FluxPipeline` object from parsed arguments. - - Overrides: - DiffusionPipeline.FromArgs - """ - MAX_BATCH_SIZE = 4 - DEVICE = "cuda" - DO_RETURN_LATENTS = False - - # Resolve all paths. - dd_path = path_module.resolve_path( - cls.get_model_names(pipeline_type), args, pipeline_type, cls._get_pipeline_uid(args.version) - ) - - return cls( - dd_path=dd_path, - version=args.version, - pipeline_type=pipeline_type, - guidance_scale=args.guidance_scale, - max_sequence_length=args.max_sequence_length, - bf16=args.bf16, - calibration_dataset=args.calibration_dataset if hasattr(args, "calibration_dataset") else None, - low_vram=args.low_vram, - torch_fallback=args.torch_fallback, - weight_streaming=args.ws, - t5_weight_streaming_budget_percentage=args.t5_ws_percentage, - transformer_weight_streaming_budget_percentage=args.transformer_ws_percentage, - max_batch_size=MAX_BATCH_SIZE, - denoising_steps=args.denoising_steps, - scheduler=args.scheduler, - lora_scale=args.lora_scale, - lora_weight=args.lora_weight, - lora_path=args.lora_path, - device=DEVICE, - output_dir=args.output_dir, - hf_token=args.hf_token, - verbose=args.verbose, - nvtx_profile=args.nvtx_profile, - use_cuda_graph=args.use_cuda_graph, - framework_model_dir=args.framework_model_dir, - return_latents=DO_RETURN_LATENTS, - torch_inference=args.torch_inference, - ) - - @classmethod - def get_model_names(cls, pipeline_type: PIPELINE_TYPE, controlnet_type: str = None) -> List[str]: - """Return a list of model names used by this pipeline. - - Overrides: - DiffusionPipeline.get_model_names - """ - if pipeline_type.is_img2img(): - return ["clip", "t5", "transformer", "vae", "vae_encoder"] - else: - return ["clip", "t5", "transformer", "vae"] - - def download_onnx_models(self, model_name: str, model_config: dict[str, Any]) -> None: - if self.fp16: - raise ValueError( - "ONNX models can be downloaded only for the following precisions: BF16, FP8, FP4. This pipeline is running in FP16." - ) - - hf_download_path = "-".join([load.get_path(self.version, self.pipeline_type.name), "onnx"]) - model_path = model_config["onnx_opt_path"] - base_dir = os.path.dirname(os.path.dirname(model_config["onnx_opt_path"])) - - if not os.path.exists(model_path): - if model_name == "clip": - dirname = "clip.opt" - elif model_name == "t5": - dirname = "t5.opt" - elif model_name == "transformer": - if model_config["use_fp4"]: - dirname = "transformer.opt/fp4" - if self.version == "flux.1-kontext-dev": - dirname = "_".join([dirname, "svd32"]) - elif model_config["use_fp8"]: - dirname = "transformer.opt/fp8" - elif self.bf16: - dirname = "transformer.opt/bf16" - elif model_name == "vae": - dirname = "vae.opt" - elif model_name == "vae_encoder": - dirname = "vae_encoder.opt" - else: - raise ValueError(f"{model_name} not found in {self.stages}") - - snapshot_download( - repo_id=hf_download_path, - allow_patterns=os.path.join(dirname, "*"), - local_dir=base_dir, - token=self.hf_token, - ) - # Rename directory from .opt to - saved_dir = os.path.join(base_dir, dirname) - model_dir = os.path.dirname(model_path) - os.rename(saved_dir, model_dir) - # Rename model from model.onnx to model_optimized.onnx - os.rename(os.path.join(model_dir, "model.onnx"), model_path) - - def is_native_export_supported(self, model_config: dict[str, Any]) -> bool: - if self.version.startswith("flux.1") and model_config["use_fp4"]: - # Native export not supported for FP4. - raise ValueError( - f"Native FP4 quantization is not supported. No ONNX model found in {model_config['onnx_opt_path']}. Please pass --download-onnx-models." - ) - if ( - self.version in ["flux.1-dev-canny", "flux.1-dev-depth"] - and model_config["use_fp8"] - and not self.calibration_dataset - ): - # Native export of FP8 model requires calibration data. - raise ValueError( - f"No ONNX model found in {model_config['onnx_opt_path']}. Please pass --download-onnx-models. If you would like to quantize and export natively, please provide calibration data using --calibration-." - ) - return True - - def _initialize_models(self, framework_model_dir, int8, fp8, fp4): - # Load text tokenizer(s) - self.tokenizer = make_tokenizer( - self.version, self.pipeline_type, self.hf_token, framework_model_dir, - ) - self.tokenizer2 = make_tokenizer( - self.version, - self.pipeline_type, - self.hf_token, - framework_model_dir, - subfolder="tokenizer_2", - tokenizer_type="t5", - ) - - # Load pipeline models - models_args = { - "version": self.version, - "pipeline": self.pipeline_type, - "device": self.device, - "hf_token": self.hf_token, - "verbose": self.verbose, - "framework_model_dir": framework_model_dir, - "max_batch_size": self.max_batch_size, - } - - self.bf16 = True if int8 or fp8 or fp4 else self.bf16 - self.fp16 = True if not self.bf16 else False - self.tf32 = True - if "clip" in self.stages: - # BF16 CLIP ONNX export fails with ComplexDouble error in newer PyTorch; use FP16. - self.models["clip"] = CLIPModel( - **models_args, - fp16=True, - tf32=self.tf32, - bf16=False, - embedding_dim=get_clip_embedding_dim(self.version, self.pipeline_type), - keep_pooled_output=True, - subfolder="text_encoder", - ) - - if "t5" in self.stages: - # Known accuracy issues with FP16 - self.models["t5"] = T5Model( - **models_args, - fp16=self.fp16, - tf32=self.tf32, - bf16=self.bf16, - subfolder="text_encoder_2", - text_maxlen=self.max_sequence_length, - weight_streaming=self.weight_streaming, - weight_streaming_budget_percentage=self.text_encoder_weight_streaming_budget_percentage, - ) - - if "vae" in self.stages: - # Accuracy issues with FP16 - self.models["vae"] = VAEModel(**models_args, fp16=False, tf32=self.tf32, bf16=self.bf16) - - self.vae_scale_factor = ( - 2 ** (len(self.models["vae"].config["block_out_channels"])) - if "vae" in self.stages and self.models["vae"] is not None - else 16 - ) - self.vae_latent_channels = ( - self.models["vae"].config["latent_channels"] - if "vae" in self.stages and self.models["vae"] is not None - else 16 - ) - - if "vae_encoder" in self.stages: - self.image_processor = VaeImageProcessor( - vae_scale_factor=self.vae_scale_factor * 2, vae_latent_channels=self.vae_latent_channels - ) - # Add kontext_resolution if available (for FluxKontextPipeline) - vae_encoder_kwargs = {} - if hasattr(self, "kontext_image") and self.kontext_image is not None: - self.resize_height, self.resize_width = self._get_resize_dimensions(self.kontext_image) - vae_encoder_kwargs["kontext_resolution"] = (self.resize_width, self.resize_height) - - self.models["vae_encoder"] = VAEEncoderModel(**models_args, fp16=False, tf32=self.tf32, bf16=self.bf16, **vae_encoder_kwargs) - - if "transformer" in self.stages: - transformer_kwargs = { - **models_args, - "bf16": self.bf16, - "fp16": self.fp16, - "int8": int8, - "fp8": fp8, - "tf32": self.tf32, - "text_maxlen": self.max_sequence_length, - "weight_streaming": self.weight_streaming, - "weight_streaming_budget_percentage": self.denoiser_weight_streaming_budget_percentage, - } - if hasattr(self, "kontext_image") and self.kontext_image is not None: - transformer_kwargs["kontext_resolution"] = (self.resize_width, self.resize_height) - self.models["transformer"] = FluxTransformerModel(**transformer_kwargs) - - def encode_image(self, input_image, encoder="vae_encoder"): - self.profile_start(encoder, color='red') - cast_to = torch.float16 if self.models[encoder].fp16 else torch.bfloat16 if self.models[encoder].bf16 else torch.float32 - input_image = input_image.to(dtype=cast_to) - if self.torch_inference or self.torch_fallback[encoder]: - image_latents = self.torch_models[encoder](input_image) - else: - image_latents = self.run_engine(encoder, {'images': input_image})['latent'] - - image_latents = self.models[encoder].config["scaling_factor"] * (image_latents - self.models[encoder].config["shift_factor"]) - self.profile_stop(encoder) - return image_latents - - # Copied from https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/flux/pipeline_flux_controlnet.py#L546 - def prepare_image( - self, - image, - width, - height, - batch_size, - num_images_per_prompt, - device, - dtype, - do_classifier_free_guidance=False, - guess_mode=False, - ): - if isinstance(image, torch.Tensor): - pass - else: - image = self.image_processor.preprocess(image, height=height, width=width) - - image_batch_size = image.shape[0] - - if image_batch_size == 1: - repeat_by = batch_size - else: - # image batch size is the same as prompt batch size - repeat_by = num_images_per_prompt - - image = image.repeat_interleave(repeat_by, dim=0) - - image = image.to(device=device, dtype=dtype) - - if do_classifier_free_guidance and not guess_mode: - image = torch.cat([image] * 2) - - return image - - # Copied from https://github.com/huggingface/diffusers/blob/v0.30.1/src/diffusers/pipelines/flux/pipeline_flux.py#L436 - @staticmethod - def _pack_latents(latents, batch_size, num_channels_latents, height, width): - """ - Reshapes latents from (B, C, H, W) to (B, H/2, W/2, C*4) as expected by the denoiser - """ - latents = latents.view( - batch_size, num_channels_latents, height // 2, 2, width // 2, 2 - ) - latents = latents.permute(0, 2, 4, 1, 3, 5) - latents = latents.reshape( - batch_size, (height // 2) * (width // 2), num_channels_latents * 4 - ) - - return latents - - # Copied from https://github.com/huggingface/diffusers/blob/v0.30.1/src/diffusers/pipelines/flux/pipeline_flux.py#L444 - @staticmethod - def _unpack_latents(latents, height, width, vae_scale_factor): - """ - Reshapes denoised latents to the format (B, C, H, W) - """ - batch_size, num_patches, channels = latents.shape - - height = height // vae_scale_factor - width = width // vae_scale_factor - - latents = latents.view(batch_size, height, width, channels // 4, 2, 2) - latents = latents.permute(0, 3, 1, 4, 2, 5) - - latents = latents.reshape( - batch_size, channels // (2 * 2), height * 2, width * 2 - ) - - return latents - - # Copied from https://github.com/huggingface/diffusers/blob/v0.30.1/src/diffusers/pipelines/flux/pipeline_flux.py#L421 - @staticmethod - def _prepare_latent_image_ids(height, width, dtype, device): - """ - Prepares latent image indices - """ - latent_image_ids = torch.zeros(height // 2, width // 2, 3) - latent_image_ids[..., 1] = ( - latent_image_ids[..., 1] + torch.arange(height // 2)[:, None] - ) - latent_image_ids[..., 2] = ( - latent_image_ids[..., 2] + torch.arange(width // 2)[None, :] - ) - - latent_image_id_height, latent_image_id_width, latent_image_id_channels = ( - latent_image_ids.shape - ) - - latent_image_ids = latent_image_ids.reshape( - latent_image_id_height * latent_image_id_width, latent_image_id_channels - ) - - return latent_image_ids.to(device=device, dtype=dtype) - - def initialize_latents( - self, - batch_size, - num_channels_latents, - latent_height, - latent_width, - latent_timestep=None, - image_latents=None, - latents_dtype=torch.float32, - ): - latents_dtype = latents_dtype # text_embeddings.dtype - latents_shape = (batch_size, num_channels_latents, latent_height, latent_width) - latents = torch.randn( - latents_shape, - device=self.device, - dtype=latents_dtype, - generator=self.generator, - ) - - if image_latents is not None: - image_latents = torch.cat([image_latents], dim=0).to(latents_dtype) - latents = self.scheduler.scale_noise(image_latents, latent_timestep, latents) - - latents = self._pack_latents( - latents, batch_size, num_channels_latents, latent_height, latent_width - ) - - latent_image_ids = self._prepare_latent_image_ids(latent_height, latent_width, latents_dtype, self.device) - - return latents, latent_image_ids - - # Copied from https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/flux/pipeline_flux_img2img.py#L416C1 - def get_timesteps(self, num_inference_steps, strength): - # get the original timestep using init_timestep - init_timestep = min(num_inference_steps * strength, num_inference_steps) - - t_start = int(max(num_inference_steps - init_timestep, 0)) - timesteps = self.scheduler.timesteps[t_start * self.scheduler.order :] - if hasattr(self.scheduler, "set_begin_index"): - self.scheduler.set_begin_index(t_start * self.scheduler.order) - - return timesteps, num_inference_steps - t_start - - def encode_prompt( - self, prompt, encoder="clip", max_sequence_length=None, pooled_output=False - ): - self.profile_start(encoder, color="green") - - tokenizer = self.tokenizer2 if encoder == "t5" else self.tokenizer - max_sequence_length = ( - tokenizer.model_max_length - if max_sequence_length is None - else max_sequence_length - ) - - def tokenize(prompt, max_sequence_length): - text_input_ids = ( - tokenizer( - prompt, - padding="max_length", - max_length=max_sequence_length, - truncation=True, - return_overflowing_tokens=False, - return_length=False, - return_tensors="pt", - ) - .input_ids.type(torch.int32) - .to(self.device) - ) - - untruncated_ids = tokenizer( - prompt, padding="longest", return_tensors="pt" - ).input_ids.type(torch.int32).to(self.device) - if untruncated_ids.shape[-1] >= text_input_ids.shape[ - -1 - ] and not torch.equal(text_input_ids, untruncated_ids): - removed_text = tokenizer.batch_decode( - untruncated_ids[:, max_sequence_length - 1 : -1] - ) - warnings.warn( - "The following part of your input was truncated because `max_sequence_length` is set to " - f"{max_sequence_length} tokens: {removed_text}" - ) - - if self.torch_inference or self.torch_fallback[encoder]: - outputs = self.torch_models[encoder]( - text_input_ids, output_hidden_states=False - ) - text_encoder_output = ( - outputs[0].clone() - if pooled_output == False - else outputs.pooler_output.clone() - ) - else: - # NOTE: output tensor for the encoder must be cloned because it will be overwritten when called again for prompt2 - outputs = self.run_engine(encoder, {"input_ids": text_input_ids}) - output_name = ( - "text_embeddings" if not pooled_output else "pooled_embeddings" - ) - text_encoder_output = outputs[output_name].clone() - - return text_encoder_output - - # Tokenize prompt - text_encoder_output = tokenize(prompt, max_sequence_length) - - self.profile_stop(encoder) - return text_encoder_output.to(torch.float16) if self.fp16 else text_encoder_output.to(torch.bfloat16) if self.bf16 else text_encoder_output - - def denoise_latent( - self, - latents, - timesteps, - text_embeddings, - pooled_embeddings, - text_ids, - latent_image_ids, - denoiser="transformer", - guidance=None, - control_latent=None, - ): - do_autocast = self.torch_inference != "" and self.models[denoiser].fp16 - with torch.autocast("cuda", enabled=do_autocast): - self.profile_start(denoiser, color="blue") - - # handle guidance - if self.models[denoiser].config["guidance_embeds"] and guidance is None: - guidance = torch.full( - [1], self.guidance_scale, device=self.device, dtype=torch.float32 - ) - guidance = guidance.expand(latents.shape[0]) - - for step_index, timestep in enumerate(timesteps): - # Prepare latents - latents_input = latents if control_latent is None else torch.cat((latents, control_latent), dim=-1) - - # prepare inputs - timestep_inp = timestep.expand(latents.shape[0]).to(latents_input.dtype) - - params = { - "hidden_states": latents_input, - "timestep": timestep_inp / 1000, - "pooled_projections": pooled_embeddings, - "encoder_hidden_states": text_embeddings, - "txt_ids": text_ids.float(), - "img_ids": latent_image_ids.float(), - } - if guidance is not None: - params.update({"guidance": guidance}) - - # Predict the noise residual - if self.torch_inference or self.torch_fallback[denoiser]: - noise_pred = self.torch_models[denoiser](**params)["sample"] - else: - noise_pred = self.run_engine(denoiser, params)["latent"] - - latents = self.scheduler.step( - noise_pred, timestep, latents, return_dict=False - )[0] - - self.profile_stop(denoiser) - return latents.to(dtype=torch.bfloat16) if self.bf16 else latents.to(dtype=torch.float32) - - def decode_latent(self, latents, decoder="vae"): - self.profile_start(decoder, color="red") - cast_to = torch.float16 if self.models[decoder].fp16 else torch.bfloat16 if self.models[decoder].bf16 else torch.float32 - latents = latents.to(dtype=cast_to) - if self.torch_inference or self.torch_fallback[decoder]: - images = self.torch_models[decoder](latents, return_dict=False)[0] - else: - images = self.run_engine(decoder, {"latent": latents})["images"] - self.profile_stop(decoder) - return images - - def print_summary(self, denoising_steps, walltime_ms, batch_size): - print("|-----------------|--------------|") - print("| {:^15} | {:^12} |".format("Module", "Latency")) - print("|-----------------|--------------|") - print( - "| {:^15} | {:>9.2f} ms |".format( - "CLIP", - cudart.cudaEventElapsedTime( - self.events["clip"][0], self.events["clip"][1] - )[1], - ) - ) - print( - "| {:^15} | {:>9.2f} ms |".format( - "T5", - cudart.cudaEventElapsedTime(self.events["t5"][0], self.events["t5"][1])[ - 1 - ], - ) - ) - if "vae_encoder" in self.stages: - print( - "| {:^15} | {:>9.2f} ms |".format( - "VAE-Enc", - cudart.cudaEventElapsedTime( - self.events["vae_encoder"][0], self.events["vae_encoder"][1] - )[1], - ) - ) - print( - "| {:^15} | {:>9.2f} ms |".format( - "Transformer x " + str(denoising_steps), - cudart.cudaEventElapsedTime( - self.events["transformer"][0], self.events["transformer"][1] - )[1], - ) - ) - print( - "| {:^15} | {:>9.2f} ms |".format( - "VAE-Dec", - cudart.cudaEventElapsedTime( - self.events["vae"][0], self.events["vae"][1] - )[1], - ) - ) - print("|-----------------|--------------|") - print("| {:^15} | {:>9.2f} ms |".format("Pipeline", walltime_ms)) - print("|-----------------|--------------|") - print("Throughput: {:.5f} image/s".format(batch_size * 1000.0 / walltime_ms)) - - def _check_integrity(self, images): - integrity_checker = PixtralContentFilter(self.device) - for image in images: - image_ = np.array(image) / 255.0 - image_ = 2 * image_ - 1 - image_ = torch.from_numpy(image_).to(self.device, dtype=torch.float32).permute(0, 3, 1, 2) - if integrity_checker.test_image(image_): - raise ValueError("Your image has been flagged. Choose another prompt/image or try again.") - - def save_images(self, prompt, images, check_integrity=False): - if check_integrity: - self._check_integrity(images) - for image in images: - self.save_image(image, self.pipeline_type.name.lower(), prompt, self.seed) - - def infer( - self, - prompt, - prompt2, - image_height, - image_width, - input_image=None, - image_strength=1.0, - control_image=None, - warmup=False, - save_image=True, - ): - """ - Run the diffusion pipeline. - - Args: - prompt (str): - The text prompt to guide image generation. - prompt2 (str): - The prompt to be sent to the T5 tokenizer and text encoder - image_height (int): - Height (in pixels) of the image to be generated. Must be a multiple of 8. - image_width (int): - Width (in pixels) of the image to be generated. Must be a multiple of 8. - input_image (PIL.Image.Image): - `Image` representing an image batch to be used as the starting point. - image_strength (`float`, *optional*, defaults to 1.0): - Indicates extent to transform the reference `image`. Must be between 0 and 1. `image` is used as a - starting point and more noise is added the higher the `strength`. The number of denoising steps depends - on the amount of noise initially added. When `strength` is 1, added noise is maximum and the denoising - process runs for the full number of iterations specified in `num_inference_steps`. A value of 1 - essentially ignores `image`. - control_image (PIL.Image.Image): - The ControlNet input condition to provide guidance to the `transformer` for generation. - warmup (bool): - Indicate if this is a warmup run. - save_image (bool): - Save the generated image (if applicable) - """ - assert len(prompt) == len(prompt2) - batch_size = len(prompt) - - # Spatial dimensions of latent tensor - latent_height = 2 * (int(image_height) // self.vae_scale_factor) - latent_width = 2 * (int(image_width) // self.vae_scale_factor) - - num_inference_steps = self.denoising_steps - latent_kwargs = {} - - with torch.inference_mode(), trt.Runtime(TRT_LOGGER): - torch.cuda.synchronize() - e2e_tic = time.perf_counter() - - num_channels_latents = self.models["transformer"].config["in_channels"] // 4 - if control_image: - num_channels_latents = self.models["transformer"].config["in_channels"] // 8 - - # Prepare control latents - control_image = self.prepare_image( - image=control_image, - width=image_width, - height=image_height, - batch_size=batch_size, - num_images_per_prompt=1, - device=self.device, - dtype=torch.float16 if self.models["vae"].fp16 else torch.bfloat16 if self.models["vae"].bf16 else torch.float32, - ) - - if control_image.ndim == 4: - with self.model_memory_manager(["vae_encoder"], low_vram=self.low_vram): - control_image = self.encode_image(control_image) - - height_control_image, width_control_image = control_image.shape[2:] - control_image = self._pack_latents( - control_image, - batch_size, - num_channels_latents, - height_control_image, - width_control_image, - ) - - # CLIP and T5 text encoder(s) - with self.model_memory_manager(["clip", "t5"], low_vram=self.low_vram): - pooled_embeddings = self.encode_prompt(prompt, pooled_output=True) - text_embeddings = self.encode_prompt( - prompt2, encoder="t5", max_sequence_length=self.max_sequence_length - ) - text_ids = torch.zeros(text_embeddings.shape[1], 3).to( - device=self.device, dtype=text_embeddings.dtype - ) - - # Prepare timesteps - sigmas = np.linspace(1.0, 1 / num_inference_steps, num_inference_steps) - image_seq_len = (latent_height // 2) * (latent_width // 2) - mu = calculate_shift( - image_seq_len, - self.scheduler.config.base_image_seq_len, - self.scheduler.config.max_image_seq_len, - self.scheduler.config.base_shift, - self.scheduler.config.max_shift, - ) - timesteps = None - # TODO: support custom timesteps - if timesteps is not None: - if ( - "timesteps" - not in inspect.signature(self.scheduler.set_timesteps).parameters - ): - raise ValueError( - f"The current scheduler class {self.scheduler.__class__}'s `set_timesteps` does not support custom" - f" timestep schedules. Please check whether you are using the correct scheduler." - ) - self.scheduler.set_timesteps(timesteps=timesteps, device=self.device) - assert self.denoising_steps == len(self.scheduler.timesteps) - else: - self.scheduler.set_timesteps(sigmas=sigmas, mu=mu, device=self.device) - timesteps = self.scheduler.timesteps.to(self.device) - num_inference_steps = len(timesteps) - - # Pre-process input image and timestep for the img2img pipeline - if input_image: - input_image = self.image_processor.preprocess(input_image, height=image_height, width=image_width).to( - self.device - ) - with self.model_memory_manager(["vae_encoder"], low_vram=self.low_vram): - image_latents = self.encode_image(input_image) - - timesteps, num_inference_steps = self.get_timesteps(self.denoising_steps, image_strength) - if num_inference_steps < 1: - raise ValueError( - f"After adjusting the num_inference_steps by strength parameter: {image_strength}, the number of pipeline" - f"steps is {num_inference_steps} which is < 1 and not appropriate for this pipeline." - ) - latent_timestep = timesteps[:1].repeat(batch_size) - - latent_kwargs.update({"image_latents": image_latents, "latent_timestep": latent_timestep}) - - # Initialize latents - latents, latent_image_ids = self.initialize_latents( - batch_size=batch_size, - num_channels_latents=num_channels_latents, - latent_height=latent_height, - latent_width=latent_width, - latents_dtype=torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32, - **latent_kwargs, - ) - - # DiT denoiser - with self.model_memory_manager(["transformer"], low_vram=self.low_vram): - latents = self.denoise_latent( - latents, - timesteps, - text_embeddings, - pooled_embeddings, - text_ids, - latent_image_ids, - control_latent=control_image, - ) - - # VAE decode latent - with self.model_memory_manager(["vae"], low_vram=self.low_vram): - latents = self._unpack_latents( - latents, image_height, image_width, self.vae_scale_factor - ) - latents = ( - latents / self.models["vae"].config["scaling_factor"] - ) + self.models["vae"].config["shift_factor"] - images = self.decode_latent(latents) - - torch.cuda.synchronize() - e2e_toc = time.perf_counter() - - walltime_ms = (e2e_toc - e2e_tic) * 1000.0 - if not warmup: - self.print_summary(num_inference_steps, walltime_ms, batch_size) - if not self.return_latents and save_image: - # post-process images - images = ( - ((images + 1) * 255 / 2) - .clamp(0, 255) - .detach() - .permute(0, 2, 3, 1) - .round() - .type(torch.uint8) - .cpu() - .numpy() - ) - - return (latents, walltime_ms) if self.return_latents else (images, walltime_ms) - - def run( - self, - prompt, - prompt2, - height, - width, - batch_count, - num_warmup_runs, - use_cuda_graph, - **kwargs, - ): - if self.low_vram and self.use_cuda_graph: - print("[W] Using low_vram, use_cuda_graph will be disabled") - self.use_cuda_graph = False - num_warmup_runs = max(1, num_warmup_runs) if use_cuda_graph else num_warmup_runs - if num_warmup_runs > 0: - print("[I] Warming up ..") - for _ in range(num_warmup_runs): - self.infer(prompt, prompt2, height, width, warmup=True, **kwargs) - - images = [] - for _ in range(batch_count): - print("[I] Running Flux pipeline") - if self.nvtx_profile: - cudart.cudaProfilerStart() - image, _ = self.infer(prompt, prompt2, height, width, warmup=False, **kwargs) - images.append(image) - if self.nvtx_profile: - cudart.cudaProfilerStop() - return images - - -class FluxKontextPipeline(FluxPipeline): - """ - Application showcasing the acceleration of Flux Kontext pipelines using Nvidia TensorRT. - This pipeline handles the specific logic for the Kontext model variant. - """ - - def __init__( - self, - kontext_image, - version="flux.1-kontext-dev", - pipeline_type=PIPELINE_TYPE.IMG2IMG, - guidance_scale=3.5, - max_sequence_length=512, - **kwargs, - ): - """ - Initializes the Flux Kontext pipeline. - - Args: - kontext_image (`PIL.Image.Image`): - Kontext Image to be edited. - version (`str`, defaults to `flux.1-kontext-dev`) - Version of the underlying Flux Kontext model. - guidance_scale (`float`, defaults to 3.5): - Guidance scale is enabled by setting as > 1. - Higher guidance scale encourages to generate images that are closely linked to the text prompt, usually at the expense of lower image quality. - max_sequence_length (`int`, defaults to 512): - Maximum sequence length to use with the `prompt`. - """ - super().__init__( - version=version, - pipeline_type=pipeline_type, - guidance_scale=guidance_scale, - max_sequence_length=max_sequence_length, - **kwargs, - ) - self.kontext_image = kontext_image - # WAR to avoid RuntimeError: ScalarType ComplexDouble is an unexpected tensor scalar type during CLIP export - self.config["clip_torch_fallback"] = True - - @classmethod - def FromArgs(cls, args: argparse.Namespace, pipeline_type: PIPELINE_TYPE) -> FluxKontextPipeline: - """Factory method to construct a `FluxKontextPipeline` object from parsed arguments. - - Overrides: - FluxPipeline.FromArgs - """ - MAX_BATCH_SIZE = 4 - DEVICE = "cuda" - DO_RETURN_LATENTS = False - - # Resolve all paths. - dd_path = path_module.resolve_path( - cls.get_model_names(pipeline_type), args, pipeline_type, cls._get_pipeline_uid(args.version) - ) - - return cls( - dd_path=dd_path, - version=args.version, - pipeline_type=pipeline_type, - guidance_scale=args.guidance_scale, - max_sequence_length=args.max_sequence_length, - bf16=args.bf16, - low_vram=args.low_vram, - torch_fallback=args.torch_fallback, - weight_streaming=args.ws, - t5_weight_streaming_budget_percentage=args.t5_ws_percentage, - transformer_weight_streaming_budget_percentage=args.transformer_ws_percentage, - max_batch_size=MAX_BATCH_SIZE, - denoising_steps=args.denoising_steps, - scheduler=args.scheduler, - lora_scale=args.lora_scale, - lora_weight=args.lora_weight, - lora_path=args.lora_path, - kontext_image=args.kontext_image if hasattr(args, "kontext_image") else None, - device=DEVICE, - output_dir=args.output_dir, - hf_token=args.hf_token, - verbose=args.verbose, - nvtx_profile=args.nvtx_profile, - use_cuda_graph=args.use_cuda_graph, - framework_model_dir=args.framework_model_dir, - return_latents=DO_RETURN_LATENTS, - torch_inference=args.torch_inference, - ) - - def initialize_latents( - self, - batch_size, - num_channels_latents, - latent_height, - latent_width, - latent_timestep=None, - image_latents=None, - latents_dtype=torch.float32, - ): - """ - Initialize latents for Kontext pipeline. - Overrides FluxPipeline.initialize_latents to handle Kontext-specific logic. - """ - latents_dtype = latents_dtype # text_embeddings.dtype - latents_shape = (batch_size, num_channels_latents, latent_height, latent_width) - latents = torch.randn( - latents_shape, - device=self.device, - dtype=latents_dtype, - generator=self.generator, - ) - - image_ids = None - if image_latents is not None: - image_latents = torch.cat([image_latents], dim=0).to(latents_dtype) - image_latent_height, image_latent_width = image_latents.shape[2:] - image_latents = self._pack_latents( - image_latents, batch_size, num_channels_latents, image_latent_height, image_latent_width - ) - image_ids = self._prepare_latent_image_ids( - image_latent_height, image_latent_width, latents_dtype, self.device - ) - # image ids are the same as latent ids with the first dimension set to 1 instead of 0 - image_ids[..., 0] = 1 - - latents = self._pack_latents(latents, batch_size, num_channels_latents, latent_height, latent_width) - - latent_ids = self._prepare_latent_image_ids(latent_height, latent_width, latents_dtype, self.device) - - latent_image_ids = torch.cat([latent_ids, image_ids], dim=0) if image_ids is not None else latent_ids - - return latents, image_latents, latent_image_ids - - def denoise_latent( - self, - latents, - timesteps, - text_embeddings, - pooled_embeddings, - text_ids, - latent_image_ids, - image_latents, - denoiser="transformer", - guidance=None, - ): - """ - Denoise latents for Kontext pipeline. - Overrides FluxPipeline.denoise_latent to handle Kontext-specific logic. - """ - do_autocast = self.torch_inference != "" and self.models[denoiser].fp16 - with torch.autocast("cuda", enabled=do_autocast): - self.profile_start(denoiser, color="blue") - - # handle guidance - if self.models[denoiser].config["guidance_embeds"] and guidance is None: - guidance = torch.full([1], self.guidance_scale, device=self.device, dtype=torch.float32) - guidance = guidance.expand(latents.shape[0]) - - for step_index, timestep in enumerate(timesteps): - # Kontext-specific: concatenate image_latents along dim=1 - latents_input = torch.cat([latents, image_latents], dim=1) - - # prepare inputs - timestep_inp = timestep.expand(latents.shape[0]).to(latents_input.dtype) - - params = { - "hidden_states": latents_input, - "timestep": timestep_inp / 1000, - "pooled_projections": pooled_embeddings, - "encoder_hidden_states": text_embeddings, - "txt_ids": text_ids.float(), - "img_ids": latent_image_ids.float(), - } - if guidance is not None: - params.update({"guidance": guidance}) - - # Predict the noise residual - if self.torch_inference or self.torch_fallback[denoiser]: - noise_pred = self.torch_models[denoiser](**params)["sample"] - else: - noise_pred = self.run_engine(denoiser, params)["latent"] - - # Kontext-specific: extract only the latent part of the prediction - noise_pred = noise_pred[:, : latents.size(1)] - - latents = self.scheduler.step(noise_pred, timestep, latents, return_dict=False)[0] - - self.profile_stop(denoiser) - return latents.to(dtype=torch.bfloat16) if self.bf16 else latents.to(dtype=torch.float32) - - def _get_resize_dimensions(self, input_image): - """ - Preprocess input image for Kontext pipeline using preferred resolutions. - Uses FluxKontextUtil to get the standardized list of preferred resolutions. - """ - multiple_of = self.vae_scale_factor * 2 - resize_height, resize_width = self.image_processor.get_default_height_width(input_image) - aspect_ratio = resize_width / resize_height - # Kontext is trained on specific resolutions, using one of them is recommended - preferred_resolutions = FluxKontextUtil.get_preferred_resolutions() - _, resize_width, resize_height = min( - (abs(aspect_ratio - w / h), w, h) for w, h in preferred_resolutions - ) - resize_width = resize_width // multiple_of * multiple_of - resize_height = resize_height // multiple_of * multiple_of - - return resize_height, resize_width - - def infer( - self, - prompt, - prompt2, - image_height, - image_width, - image_strength=1.0, - warmup=False, - save_image=True, - ): - """ - Run the Kontext diffusion pipeline. - - Args: - prompt (str): - The text prompt to guide image generation. - prompt2 (str): - The prompt to be sent to the T5 tokenizer and text encoder - image_height (int): - Height (in pixels) of the image to be generated. Must be a multiple of 8. - image_width (int): - Width (in pixels) of the image to be generated. Must be a multiple of 8. - image_strength (`float`, *optional*, defaults to 1.0): - Indicates extent to transform the reference `image`. Must be between 0 and 1. `image` is used as a - starting point and more noise is added the higher the `strength`. The number of denoising steps depends - on the amount of noise initially added. When `strength` is 1, added noise is maximum and the denoising - process runs for the full number of iterations specified in `num_inference_steps`. A value of 1 - essentially ignores `image`. - warmup (bool): - Indicate if this is a warmup run. - save_image (bool): - Save the generated image (if applicable) - """ - assert len(prompt) == len(prompt2) - batch_size = len(prompt) - - # Spatial dimensions of latent tensor - latent_height = 2 * (int(image_height) // self.vae_scale_factor) - latent_width = 2 * (int(image_width) // self.vae_scale_factor) - - num_inference_steps = self.denoising_steps - latent_kwargs = {} - - with torch.inference_mode(), trt.Runtime(TRT_LOGGER): - torch.cuda.synchronize() - e2e_tic = time.perf_counter() - - num_channels_latents = self.models["transformer"].config["in_channels"] // 4 - - # CLIP and T5 text encoder(s) - with self.model_memory_manager(["clip", "t5"], low_vram=self.low_vram): - pooled_embeddings = self.encode_prompt(prompt, pooled_output=True) - text_embeddings = self.encode_prompt( - prompt2, encoder="t5", max_sequence_length=self.max_sequence_length - ) - text_ids = torch.zeros(text_embeddings.shape[1], 3).to(device=self.device, dtype=text_embeddings.dtype) - - # Prepare timesteps - sigmas = np.linspace(1.0, 1 / num_inference_steps, num_inference_steps) - image_seq_len = (latent_height // 2) * (latent_width // 2) - mu = calculate_shift( - image_seq_len, - self.scheduler.config.base_image_seq_len, - self.scheduler.config.max_image_seq_len, - self.scheduler.config.base_shift, - self.scheduler.config.max_shift, - ) - timesteps = None - # TODO: support custom timesteps - if timesteps is not None: - if "timesteps" not in inspect.signature(self.scheduler.set_timesteps).parameters: - raise ValueError( - f"The current scheduler class {self.scheduler.__class__}'s `set_timesteps` does not support custom" - f" timestep schedules. Please check whether you are using the correct scheduler." - ) - self.scheduler.set_timesteps(timesteps=timesteps, device=self.device) - assert self.denoising_steps == len(self.scheduler.timesteps) - else: - self.scheduler.set_timesteps(sigmas=sigmas, mu=mu, device=self.device) - timesteps = self.scheduler.timesteps.to(self.device) - num_inference_steps = len(timesteps) - - # Pre-process kontext image and timestep for the img2img pipeline - if self.kontext_image: - # Kontext-specific image preprocessing - kontext_image = self.image_processor.resize(self.kontext_image, self.resize_height, self.resize_width) - - kontext_image = self.image_processor.preprocess( - kontext_image, height=self.resize_height, width=self.resize_width - ).to(self.device) - with self.model_memory_manager(["vae_encoder"], low_vram=self.low_vram): - image_latents = self.encode_image(kontext_image) - - timesteps, num_inference_steps = self.get_timesteps(self.denoising_steps, image_strength) - if num_inference_steps < 1: - raise ValueError( - f"After adjusting the num_inference_steps by strength parameter: {image_strength}, the number of pipeline" - f"steps is {num_inference_steps} which is < 1 and not appropriate for this pipeline." - ) - latent_timestep = timesteps[:1].repeat(batch_size) - - latent_kwargs.update({"image_latents": image_latents, "latent_timestep": latent_timestep}) - - # Initialize latents - latents, image_latents, latent_ids = self.initialize_latents( - batch_size=batch_size, - num_channels_latents=num_channels_latents, - latent_height=latent_height, - latent_width=latent_width, - latents_dtype=torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32, - **latent_kwargs, - ) - - # DiT denoiser - with self.model_memory_manager(["transformer"], low_vram=self.low_vram): - latents = self.denoise_latent( - latents, - timesteps, - text_embeddings, - pooled_embeddings, - text_ids, - latent_ids, - image_latents, - ) - - # VAE decode latent - with self.model_memory_manager(["vae"], low_vram=self.low_vram): - latents = self._unpack_latents(latents, image_height, image_width, self.vae_scale_factor) - latents = (latents / self.models["vae"].config["scaling_factor"]) + self.models["vae"].config[ - "shift_factor" - ] - images = self.decode_latent(latents) - - torch.cuda.synchronize() - e2e_toc = time.perf_counter() - - walltime_ms = (e2e_toc - e2e_tic) * 1000.0 - if not warmup: - self.print_summary(num_inference_steps, walltime_ms, batch_size) - if not self.return_latents and save_image: - # post-process images - images = ( - ((images + 1) * 255 / 2) - .clamp(0, 255) - .detach() - .permute(0, 2, 3, 1) - .round() - .type(torch.uint8) - .cpu() - .numpy() - ) - - return (latents, walltime_ms) if self.return_latents else (images, walltime_ms) diff --git a/demo/Diffusion/demo_diffusion/pipeline/model_memory_manager.py b/demo/Diffusion/demo_diffusion/pipeline/model_memory_manager.py deleted file mode 100644 index c34ec47d8..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/model_memory_manager.py +++ /dev/null @@ -1,74 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import torch -from cuda.bindings import runtime as cudart - - -class ModelMemoryManager: - """ - Context manager for efficiently loading and unloading models to optimize VRAM usage. - - This class provides a context to temporarily load models into GPU memory for inference - and automatically unload them afterward. It's especially useful in low VRAM environments - where models need to be swapped in and out of GPU memory. - - Args: - parent: The parent class instance that contains the model references and resources. - model_names (list): List of model names to load and unload. - low_vram (bool, optional): If True, enables VRAM optimization. If False, the context manager does nothing. Defaults to False. - """ - - def __init__(self, parent, model_names, low_vram=False): - self.parent = parent - self.model_names = model_names - self.low_vram = low_vram - self.device_memories = {} - - def __enter__(self): - if not self.low_vram: - return - for model_name in self.model_names: - if not self.parent.torch_fallback[model_name]: - # creating engine object (load from plan file) - self.parent.engine[model_name].load() - # allocate device memory - _, shared_device_memory = cudart.cudaMalloc(self.parent.device_memory_sizes[model_name]) - self.device_memories[model_name] = shared_device_memory - # creating context - self.parent.engine[model_name].activate(device_memory=shared_device_memory) - # creating input and output buffer - self.parent.engine[model_name].allocate_buffers( - shape_dict=self.parent.shape_dicts[model_name], device=self.parent.device - ) - else: - print(f"[I] Reloading torch model {model_name} from cpu.") - self.parent.torch_models[model_name] = self.parent.torch_models[model_name].to("cuda") - - def __exit__(self, exc_type, exc_val, exc_tb): - if not self.low_vram: - return - for model_name in self.model_names: - if not self.parent.torch_fallback[model_name]: - self.parent.engine[model_name].deallocate_buffers() - self.parent.engine[model_name].deactivate() - self.parent.engine[model_name].unload() - cudart.cudaFree(self.device_memories.pop(model_name)) - else: - print(f"[I] Offloading torch model {model_name} to cpu.") - self.parent.torch_models[model_name] = self.parent.torch_models[model_name].to("cpu") - torch.cuda.empty_cache() diff --git a/demo/Diffusion/demo_diffusion/pipeline/stable_cascade_pipeline.py b/demo/Diffusion/demo_diffusion/pipeline/stable_cascade_pipeline.py deleted file mode 100644 index 5abeab1c5..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/stable_cascade_pipeline.py +++ /dev/null @@ -1,343 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import inspect -import time - -import tensorrt as trt -import torch -from cuda.bindings import runtime as cudart -from diffusers import DDPMWuerstchenScheduler - -from demo_diffusion.model import ( - CLIPWithProjModel, - UNetCascadeModel, - VQGANModel, - make_tokenizer, -) -from demo_diffusion.pipeline.stable_diffusion_pipeline import StableDiffusionPipeline -from demo_diffusion.pipeline.type import PIPELINE_TYPE - -TRT_LOGGER = trt.Logger(trt.Logger.ERROR) - - -class StableCascadePipeline(StableDiffusionPipeline): - """ - Application showcasing the acceleration of Stable Cascade pipelines using NVidia TensorRT. - """ - def __init__( - self, - version='cascade', - pipeline_type=PIPELINE_TYPE.CASCADE_PRIOR, - latent_dim_scale=10.67, - lite=False, - **kwargs - ): - """ - Initializes the Stable Cascade pipeline. - - Args: - version (str): - The version of the pipeline. Should be one of [cascade] - pipeline_type (PIPELINE_TYPE): - Type of current pipeline. - latent_dim_scale (float): - Multiplier to determine the VQ latent space size from the image embeddings. If the image embeddings are - height=24 and width=24, the VQ latent shape needs to be height=int(24*10.67)=256 and - width=int(24*10.67)=256 in order to match the training conditions. - lite (bool): - Boolean indicating if the Lite Version of the Stage B and Stage C models is to be used - """ - super().__init__( - version=version, - pipeline_type=pipeline_type, - **kwargs - ) - self.config['clip_hidden_states'] = True - # from Diffusers: https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/stable_cascade/pipeline_stable_cascade.py#L91C9-L91C41 - self.latent_dim_scale = latent_dim_scale - self.lite = lite - - def initializeModels(self, framework_model_dir, int8, fp8): - # Load text tokenizer(s) - self.tokenizer = make_tokenizer(self.version, self.pipeline_type, self.hf_token, framework_model_dir) - - # Load pipeline models - models_args = {'version': self.version, 'pipeline': self.pipeline_type, 'device': self.device, - 'hf_token': self.hf_token, 'verbose': self.verbose, 'framework_model_dir': framework_model_dir, - 'max_batch_size': self.max_batch_size} - - self.fp16 = False # TODO: enable FP16 mode for decoder model (requires strongly typed engine) - self.bf16 = True - if 'clip' in self.stages: - self.models['clip'] = CLIPWithProjModel(**models_args, fp16=self.fp16, bf16=self.bf16, output_hidden_states=self.config.get('clip_hidden_states', False), subfolder='text_encoder') - - if 'unet' in self.stages: - self.models['unet'] = UNetCascadeModel(**models_args, fp16=self.fp16, bf16=self.bf16, lite=self.lite, do_classifier_free_guidance=self.do_classifier_free_guidance) - - if 'vqgan' in self.stages: - self.models['vqgan'] = VQGANModel(**models_args, fp16=self.fp16, bf16=self.bf16, latent_dim_scale = self.latent_dim_scale) - - def encode_prompt(self, prompt, negative_prompt, encoder='clip', pooled_outputs=False, output_hidden_states=False): - self.profile_start(encoder, color='green') - - tokenizer = self.tokenizer - - def tokenize(prompt, output_hidden_states): - text_inputs = tokenizer( - prompt, - padding="max_length", - max_length=tokenizer.model_max_length, - truncation=True, - return_tensors="pt", - ) - text_input_ids = text_inputs.input_ids.type(torch.int32).to(self.device) - attention_mask = text_inputs.attention_mask.type(torch.int32).to(self.device) - - text_hidden_states = None - if self.torch_inference: - outputs = self.torch_models[encoder](text_input_ids, attention_mask=attention_mask, output_hidden_states=output_hidden_states) - text_embeddings = outputs[0].clone() - if output_hidden_states: - hidden_state_layer = -1 - text_hidden_states = outputs['hidden_states'][hidden_state_layer].clone() - else: - # NOTE: output tensor for CLIP must be cloned because it will be overwritten when called again for negative prompt - outputs = self.runEngine(encoder, {'input_ids': text_input_ids, 'attention_mask': attention_mask}) - text_embeddings = outputs['text_embeddings'].clone() - if output_hidden_states: - text_hidden_states = outputs['hidden_states'].clone() - - return text_embeddings, text_hidden_states - - # Tokenize prompt - text_embeddings, text_hidden_states = tokenize(prompt, output_hidden_states) - - if self.do_classifier_free_guidance: - # Tokenize negative prompt - uncond_embeddings, uncond_hidden_states = tokenize(negative_prompt, output_hidden_states) - - # Concatenate the unconditional and text embeddings into a single batch to avoid doing two forward passes for classifier free guidance - text_embeddings = torch.cat([text_embeddings, uncond_embeddings]) - - if pooled_outputs: - pooled_output = text_embeddings - - if output_hidden_states: - text_embeddings = torch.cat([text_hidden_states, uncond_hidden_states]) if self.do_classifier_free_guidance else text_hidden_states - - self.profile_stop(encoder) - if pooled_outputs: - return text_embeddings, pooled_output - return text_embeddings - - def denoise_latent(self, - latents, - pooled_embeddings, - text_embeddings=None, - image_embeds=None, - effnet=None, - denoiser='unet', - timesteps=None, - ): - - do_autocast = False - with torch.autocast('cuda', enabled=do_autocast): - self.profile_start(denoiser, color='blue') - for step_index, timestep in enumerate(timesteps): - # ratio input required for stable cascade prior - timestep_ratio = timestep.expand(latents.size(0)).to(latents.dtype) - # Expand the latents and timestep_ratio if we are doing classifier free guidance - latent_model_input = torch.cat([latents] * 2) if self.do_classifier_free_guidance else latents - timestep_ratio_input = torch.cat([timestep_ratio] * 2) if self.do_classifier_free_guidance else timestep_ratio - - params = {"sample": latent_model_input, "timestep_ratio": timestep_ratio_input, "clip_text_pooled": pooled_embeddings} - if text_embeddings is not None: - params.update({'clip_text': text_embeddings}) - if image_embeds is not None: - params.update({'clip_img': image_embeds}) - if effnet is not None: - params.update({'effnet': effnet}) - - # Predict the noise residual - if self.torch_inference: - noise_pred = self.torch_models[denoiser](**params)['sample'] - else: - noise_pred = self.runEngine(denoiser, params)['latent'] - - # Perform guidance - if self.do_classifier_free_guidance: - noise_pred_text, noise_pred_uncond = noise_pred.chunk(2) - noise_pred = noise_pred_uncond + self.guidance_scale * (noise_pred_text - noise_pred_uncond) - - # from diffusers (prepare_extra_step_kwargs) - extra_step_kwargs = {} - if "eta" in set(inspect.signature(self.scheduler.step).parameters.keys()): - # TODO: configurable eta - eta = 0.0 - extra_step_kwargs["eta"] = eta - if "generator" in set(inspect.signature(self.scheduler.step).parameters.keys()): - extra_step_kwargs["generator"] = self.generator - - latents = self.scheduler.step(noise_pred, timestep_ratio, latents, **extra_step_kwargs, return_dict=False)[0] - - latents = latents.to(dtype=torch.bfloat16 if self.bf16 else torch.float32) - - self.profile_stop(denoiser) - return latents - - def decode_latent(self, latents, model_name='vqgan'): - self.profile_start(model_name, color='red') - latents = self.models[model_name].scale_factor * latents - if self.torch_inference: - images = self.torch_models[model_name](latents)['sample'] - else: - images = self.runEngine(model_name, {'latent': latents})['images'] - self.profile_stop(model_name) - return images - - def print_summary(self, denoising_steps, walltime_ms, batch_size): - print('|-----------------|--------------|') - print('| {:^15} | {:^12} |'.format('Module', 'Latency')) - print('|-----------------|--------------|') - for stage in self.stages: - stage_name = stage + ' x ' + str(denoising_steps) if stage == 'unet' else stage - print( - "| {:^15} | {:>9.2f} ms |".format( - stage_name, cudart.cudaEventElapsedTime(self.events[stage][0], self.events[stage][1])[1], - ) - ) - print('|-----------------|--------------|') - print('| {:^15} | {:>9.2f} ms |'.format('Pipeline', walltime_ms)) - print('|-----------------|--------------|') - print('Throughput: {:.5f} image/s'.format(batch_size*1000./walltime_ms)) - - def infer( - self, - prompt, - negative_prompt, - image_height, - image_width, - image_embeddings=None, - warmup=False, - verbose=False, - save_image=True, - ): - """ - Run the diffusion pipeline. - - Args: - prompt (str): - The text prompt to guide image generation. - negative_prompt (str): - The prompt not to guide the image generation. - image_height (int): - Height (in pixels) of the image to be generated. Must be a multiple of 8. - image_width (int): - Width (in pixels) of the image to be generated. Must be a multiple of 8. - image_embeddings (`torch.FloatTensor` or `List[torch.FloatTensor]`): - Image Embeddings either extracted from an image or generated by a Prior Model. - warmup (bool): - Indicate if this is a warmup run. - verbose (bool): - Verbose in logging - save_image (bool): - Save the generated image (if applicable) - """ - if self.pipeline_type.is_cascade_decoder(): - assert image_embeddings is not None, "Image Embeddings are required to run the decoder. Provided None" - assert len(prompt) == len(negative_prompt) - batch_size = len(prompt) - - # Spatial dimensions of latent tensor - latent_height = image_height // 42 - latent_width = image_width // 42 - - if image_embeddings is not None: - assert latent_height == image_embeddings.shape[-2] - assert latent_width == image_embeddings.shape[-1] - - if self.generator and self.seed: - self.generator.manual_seed(self.seed) - - num_inference_steps = self.denoising_steps - - with torch.inference_mode(), trt.Runtime(TRT_LOGGER): - torch.cuda.synchronize() - e2e_tic = time.perf_counter() - - denoise_kwargs = {} - # TODO: support custom timesteps - timesteps = None - if timesteps is not None: - if "timesteps" not in set(inspect.signature(self.scheduler.set_timesteps).parameters.keys()): - raise ValueError( - f"The current scheduler class {self.scheduler.__class__}'s `set_timesteps` does not support custom" - f" timestep schedules. Please check whether you are using the correct scheduler." - ) - self.scheduler.set_timesteps(timesteps=timesteps, device=self.device) - assert self.denoising_steps == len(self.scheduler.timesteps) - else: - self.scheduler.set_timesteps(self.denoising_steps, device=self.device) - timesteps = self.scheduler.timesteps.to(self.device) - if isinstance(self.scheduler, DDPMWuerstchenScheduler): - timesteps = timesteps[:-1] - denoise_kwargs.update({'timesteps': timesteps}) - - # Initialize latents - latents_dtpye = torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32 - latents = self.initialize_latents( - batch_size=batch_size, - unet_channels=16 if self.pipeline_type.is_cascade_prior() else 4, # TODO: can we query "in_channels" from config - latent_height=latent_height if self.pipeline_type.is_cascade_prior() else int(latent_height * self.latent_dim_scale), - latent_width=latent_width if self.pipeline_type.is_cascade_prior() else int(latent_width * self.latent_dim_scale), - latents_dtype=latents_dtpye - ) - - # CLIP text encoder(s) - text_embeddings, pooled_embeddings = self.encode_prompt(prompt, negative_prompt, - encoder='clip', pooled_outputs=True, output_hidden_states=True) - - if self.pipeline_type.is_cascade_prior(): - denoise_kwargs.update({'text_embeddings': text_embeddings}) - - # image embeds - image_embeds_pooled = torch.zeros(batch_size, 1, 768, device=self.device, dtype=latents_dtpye) - image_embeds = (torch.cat([image_embeds_pooled, torch.zeros_like(image_embeds_pooled)]) if self.do_classifier_free_guidance else image_embeddings) - denoise_kwargs.update({'image_embeds': image_embeds}) - else: - effnet = (torch.cat([image_embeddings, torch.zeros_like(image_embeddings)]) if self.do_classifier_free_guidance else image_embeddings) - denoise_kwargs.update({'effnet': effnet}) - - # UNet denoiser - latents = self.denoise_latent(latents, pooled_embeddings.unsqueeze(1), denoiser='unet', **denoise_kwargs) - - if not self.return_latents: - images = self.decode_latent(latents) - - torch.cuda.synchronize() - e2e_toc = time.perf_counter() - - walltime_ms = (e2e_toc - e2e_tic) * 1000. - if not warmup: - self.print_summary(num_inference_steps, walltime_ms, batch_size) - if not self.return_latents and save_image: - # post-process images - images = ((images) * 255).clamp(0, 255).detach().permute(0, 2, 3, 1).round().type(torch.uint8).cpu().numpy() - self.save_image(images, self.pipeline_type.name.lower(), prompt, self.seed) - - return (latents, walltime_ms) if self.return_latents else (images, walltime_ms) diff --git a/demo/Diffusion/demo_diffusion/pipeline/stable_diffusion_35_pipeline.py b/demo/Diffusion/demo_diffusion/pipeline/stable_diffusion_35_pipeline.py deleted file mode 100644 index 8c142dbe8..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/stable_diffusion_35_pipeline.py +++ /dev/null @@ -1,952 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -from __future__ import annotations - -import argparse -import inspect -import os -import time -import warnings -from typing import Any, List, Union - -import tensorrt as trt -import torch -from cuda.bindings import runtime as cudart -from diffusers.image_processor import VaeImageProcessor -from huggingface_hub import snapshot_download -from transformers import PreTrainedTokenizerBase - -from demo_diffusion import path as path_module -from demo_diffusion.model import ( - CLIPWithProjModel, - SD3ControlNet, - SD3TransformerModel, - T5Model, - VAEEncoderModel, - VAEModel, - load, - make_tokenizer, -) -from demo_diffusion.pipeline.diffusion_pipeline import DiffusionPipeline -from demo_diffusion.pipeline.type import PIPELINE_TYPE - -TRT_LOGGER = trt.Logger(trt.Logger.ERROR) - -class SD3CannyImageProcessor(VaeImageProcessor): - def __init__(self): - super().__init__(do_normalize=False) - def preprocess(self, image, **kwargs): - image = super().preprocess(image, **kwargs) - image = image * 255 * 0.5 + 0.5 - return image - def postprocess(self, image, do_denormalize=True, **kwargs): - do_denormalize = [True] * image.shape[0] - image = super().postprocess(image, **kwargs, do_denormalize=do_denormalize) - return image - -class StableDiffusion35Pipeline(DiffusionPipeline): - """ - Application showcasing the acceleration of Stable Diffusion 3.5 pipelines using Nvidia TensorRT. - """ - - def __init__( - self, - version: str, - pipeline_type=PIPELINE_TYPE.TXT2IMG, - guidance_scale: float = 7.0, - max_sequence_length: int = 256, - controlnet=None, - **kwargs, - ): - """ - Initializes the Stable Diffusion 3.5 pipeline. - - Args: - version (str): - The version of the pipeline. Should be one of ['3.5-medium', '3.5-large'] - pipeline_type (PIPELINE_TYPE): - Type of current pipeline. - guidance_scale (`float`, defaults to 7.0): - Guidance scale is enabled by setting as > 1. - Higher guidance scale encourages to generate images that are closely linked to the text prompt, usually at the expense of lower image quality. - max_sequence_length (`int`, defaults to 256): - Maximum sequence length to use with the `prompt`. - controlnet (str): - Which ControlNet to use. - """ - super().__init__(version=version, pipeline_type=pipeline_type, controlnet=controlnet, **kwargs) - - self.fp16 = True if not self.bf16 else False - - self.force_weakly_typed_t5 = False - self.config["clip_g_torch_fallback"] = True - self.config["clip_l_torch_fallback"] = True - self.config["clip_hidden_states"] = True - self.controlnet = controlnet - - self.guidance_scale = guidance_scale - self.do_classifier_free_guidance = self.guidance_scale > 1 - self.max_sequence_length = max_sequence_length - - @classmethod - def FromArgs(cls, args: argparse.Namespace, pipeline_type: PIPELINE_TYPE) -> StableDiffusion35Pipeline: - """Factory method to construct a `StableDiffusion35Pipeline` object from parsed arguments. - - Overrides: - DiffusionPipeline.FromArgs - """ - MAX_BATCH_SIZE = 4 - DEVICE = "cuda" - DO_RETURN_LATENTS = False - - # Resolve all paths. - controlnet_type = args.controlnet_type if "controlnet_type" in args else None - dd_path = path_module.resolve_path( - cls.get_model_names(pipeline_type, controlnet_type), - args, - pipeline_type, - cls._get_pipeline_uid(args.version), - ) - - return cls( - dd_path=dd_path, - version=args.version, - pipeline_type=pipeline_type, - guidance_scale=args.guidance_scale, - max_sequence_length=args.max_sequence_length, - controlnet=controlnet_type, - bf16=args.bf16, - low_vram=args.low_vram, - torch_fallback=args.torch_fallback, - weight_streaming=args.ws, - max_batch_size=MAX_BATCH_SIZE, - denoising_steps=args.denoising_steps, - scheduler=args.scheduler, - device=DEVICE, - output_dir=args.output_dir, - hf_token=args.hf_token, - verbose=args.verbose, - nvtx_profile=args.nvtx_profile, - use_cuda_graph=args.use_cuda_graph, - framework_model_dir=args.framework_model_dir, - return_latents=DO_RETURN_LATENTS, - torch_inference=args.torch_inference, - ) - - @classmethod - def get_model_names(cls, pipeline_type: PIPELINE_TYPE, controlnet_type: str = None) -> List[str]: - """Return a list of model names used by this pipeline. - - Overrides: - DiffusionPipeline.get_model_names - """ - if pipeline_type.is_controlnet(): - assert controlnet_type, "ControlNet type must be specified for ControlNet pipelines" - return ["clip_l", "clip_g", "t5", "transformer", "vae", "vae_encoder", f"controlnet_{controlnet_type}"] - return ["clip_l", "clip_g", "t5", "transformer", "vae"] - - def download_onnx_models(self, model_name: str, model_config: dict[str, Any]) -> None: - if self.fp16: - raise ValueError( - "ONNX models can be downloaded only for the following precisions: BF16, FP8. This pipeline is running in FP16." - ) - - hf_download_path = "-".join([load.get_path(self.version, self.pipeline_type.name), "tensorrt"]) - model_path = model_config["onnx_opt_path"] - base_dir = os.path.dirname(os.path.dirname(model_config["onnx_opt_path"])) - - if not os.path.exists(model_path): - if model_name == "transformer": - if model_config["use_fp8"]: - dirname = os.path.join(model_name, "fp8") - elif self.bf16: - dirname = os.path.join(model_name, "bf16") - elif "controlnet" in model_name: - hf_download_path_cnet = hf_download_path.replace("large", "controlnets") - dirname = f"controlnet_{self.controlnet}" - if "blur" in model_name: - pass - elif model_config["use_fp8"]: - dirname = os.path.join(dirname, "fp8") - elif self.bf16: - dirname = os.path.join(dirname, "bf16") - elif model_name in self.stages: - dirname = model_name - else: - raise ValueError(f"{model_name} not found in {self.stages}") - - dirname = os.path.join("ONNX", dirname) - snapshot_download( - repo_id=hf_download_path if "controlnet" not in model_name else hf_download_path_cnet, - allow_patterns=os.path.join(dirname, "*"), - local_dir=base_dir, - token=self.hf_token, - ) - # Rename directory from ONNX/ to - saved_dir = os.path.join(base_dir, dirname) - model_dir = os.path.dirname(model_path) - os.rename(saved_dir, model_dir) - - def load_resources( - self, - image_height: int, - image_width: int, - batch_size: int, - seed: int, - ): - super().load_resources(image_height, image_width, batch_size, seed) - - def _initialize_models(self, framework_model_dir, int8, fp8, fp4): - # Load text tokenizer(s) - self.tokenizer = make_tokenizer( - self.version, - self.pipeline_type, - self.hf_token, - framework_model_dir, - ) - self.tokenizer2 = make_tokenizer( - self.version, - self.pipeline_type, - self.hf_token, - framework_model_dir, - subfolder="tokenizer_2", - ) - self.tokenizer3 = make_tokenizer( - self.version, - self.pipeline_type, - self.hf_token, - framework_model_dir, - subfolder="tokenizer_3", - tokenizer_type="t5", - ) - - # Load pipeline models - models_args = { - "version": self.version, - "pipeline": self.pipeline_type, - "device": self.device, - "hf_token": self.hf_token, - "verbose": self.verbose, - "framework_model_dir": framework_model_dir, - "max_batch_size": self.max_batch_size, - } - - self.bf16 = True if int8 or fp8 or fp4 else self.bf16 - self.fp16 = True if not self.bf16 else False - self.tf32 = True - self.fp8 = fp8 - self.int8 = int8 - self.fp4 = fp4 - if "clip_l" in self.stages: - self.models["clip_l"] = CLIPWithProjModel( - **models_args, - fp16=self.fp16, - bf16=self.bf16, - subfolder="text_encoder", - output_hidden_states=self.config.get("clip_hidden_states", False), - ) - - if "clip_g" in self.stages: - self.models["clip_g"] = CLIPWithProjModel( - **models_args, - fp16=self.fp16, - bf16=self.bf16, - subfolder="text_encoder_2", - output_hidden_states=self.config.get("clip_hidden_states", False), - ) - - if "t5" in self.stages: - # Known accuracy issues with FP16 - self.models["t5"] = T5Model( - **models_args, - fp16=self.fp16, - bf16=self.bf16, - tf32=self.tf32, - subfolder="text_encoder_3", - text_maxlen=self.max_sequence_length, - weight_streaming=self.weight_streaming, - weight_streaming_budget_percentage=self.text_encoder_weight_streaming_budget_percentage, - ) - - if "transformer" in self.stages: - self.models["transformer"] = SD3TransformerModel( - **models_args, - fp16=self.fp16, - tf32=self.tf32, - bf16=self.bf16, - fp8=self.fp8, - int8=self.int8, - fp4=self.fp4, - text_maxlen=self.models["t5"].text_maxlen + self.models["clip_g"].text_maxlen, - weight_streaming=self.weight_streaming, - do_classifier_free_guidance=self.do_classifier_free_guidance, - ) - - if f"controlnet_{self.controlnet}" in self.stages: - self.models[f"controlnet_{self.controlnet}"] = SD3ControlNet( - **models_args, - fp16=self.fp16, - tf32=self.tf32, - bf16=self.bf16, - do_classifier_free_guidance=self.do_classifier_free_guidance, - controlnet=self.controlnet, - ) - - if "vae" in self.stages: - self.models["vae"] = VAEModel(**models_args, fp16=self.fp16, tf32=self.tf32, bf16=self.bf16) - - self.vae_scale_factor = ( - 2 ** (len(self.models["vae"].config["block_out_channels"]) - 1) if "vae" in self.models else 8 - ) - self.patch_size = ( - self.models["transformer"].config["patch_size"] - if "transformer" in self.stages and self.models["transformer"] is not None - else 2 - ) - - if "vae_encoder" in self.stages: - self.models["vae_encoder"] = VAEEncoderModel(**models_args, fp16=False, tf32=self.tf32, bf16=self.bf16, do_classifier_free_guidance=self.do_classifier_free_guidance) - self.vae_latent_channels = ( - self.models["vae"].config["latent_channels"] - if "vae" in self.stages and self.models["vae"] is not None - else 16 - ) - if self.controlnet and "canny" in self.controlnet: - self.image_processor = SD3CannyImageProcessor() - else: - self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor) - - def print_summary(self, denoising_steps, walltime_ms): - print("|-----------------|--------------|") - print("| {:^15} | {:^12} |".format("Module", "Latency")) - print("|-----------------|--------------|") - for stage in self.stages: - # controlnet is profiled in the denoising step - if "controlnet" in stage: - continue - stage_name = stage - if "transformer" in stage: - if f"controlnet_{self.controlnet}" in self.stages: - stage_name += '+cnet' - stage_name += ' x ' + str(denoising_steps) - print( - "| {:^15} | {:>9.2f} ms |".format( - stage_name, cudart.cudaEventElapsedTime(self.events[stage][0], self.events[stage][1])[1], - ) - ) - print("|-----------------|--------------|") - print("| {:^15} | {:>9.2f} ms |".format("Pipeline", walltime_ms)) - print("|-----------------|--------------|") - print("Throughput: {:.5f} image/s".format(self.batch_size * 1000.0 / walltime_ms)) - - @staticmethod - def _tokenize( - tokenizer: PreTrainedTokenizerBase, - prompt: list[str], - max_sequence_length: int, - device: torch.device, - ): - text_input_ids = tokenizer( - prompt, - padding="max_length", - max_length=max_sequence_length, - truncation=True, - add_special_tokens=True, - return_tensors="pt", - ).input_ids - text_input_ids = text_input_ids.type(torch.int32) - - untruncated_ids = tokenizer( - prompt, - padding="longest", - return_tensors="pt", - ).input_ids.type(torch.int32) - - if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal(text_input_ids, untruncated_ids): - removed_text = tokenizer.batch_decode(untruncated_ids[:, max_sequence_length - 1 : -1]) - warnings.warn( - "The following part of your input was truncated because `max_sequence_length` is set to " - f" {max_sequence_length} tokens: {removed_text}" - ) - text_input_ids = text_input_ids.to(device) - return text_input_ids - - def _get_prompt_embed( - self, - prompt: list[str], - encoder_name: str, - domain="positive_prompt", - ): - if encoder_name == "clip_l": - tokenizer = self.tokenizer - max_sequence_length = tokenizer.model_max_length - output_hidden_states = True - elif encoder_name == "clip_g": - tokenizer = self.tokenizer2 - max_sequence_length = tokenizer.model_max_length - output_hidden_states = True - elif encoder_name == "t5": - tokenizer = self.tokenizer3 - max_sequence_length = self.max_sequence_length - output_hidden_states = False - else: - raise NotImplementedError(f"encoder not found: {encoder_name}") - - self.profile_start(encoder_name, color="green", domain=domain) - - text_input_ids = self._tokenize( - tokenizer=tokenizer, - prompt=prompt, - device=self.device, - max_sequence_length=max_sequence_length, - ) - - text_hidden_states = None - if self.torch_inference or self.torch_fallback[encoder_name]: - outputs = self.torch_models[encoder_name]( - text_input_ids, - output_hidden_states=output_hidden_states, - ) - text_embeddings = outputs[0].clone() - if output_hidden_states: - text_hidden_states = outputs["hidden_states"][-2].clone() - else: - # NOTE: output tensor for the encoder must be cloned because it will be overwritten when called again for prompt2 - outputs = self.run_engine(encoder_name, {"input_ids": text_input_ids}) - text_embeddings = outputs["text_embeddings"].clone() - if output_hidden_states: - text_hidden_states = outputs["hidden_states"].clone() - - self.profile_stop(encoder_name) - return text_hidden_states, text_embeddings - - @staticmethod - def _duplicate_text_embed( - prompt_embed: torch.Tensor, - batch_size: int, - num_images_per_prompt: int, - pooled_prompt_embed: torch.Tensor | None = None, - ): - _, seq_len, _ = prompt_embed.shape - # duplicate text embeddings for each generation per prompt, using mps friendly method - prompt_embed = prompt_embed.repeat(1, num_images_per_prompt, 1) - prompt_embed = prompt_embed.view(batch_size * num_images_per_prompt, seq_len, -1) - - if pooled_prompt_embed is not None: - pooled_prompt_embed = pooled_prompt_embed.repeat(1, num_images_per_prompt, 1) - pooled_prompt_embed = pooled_prompt_embed.view(batch_size * num_images_per_prompt, -1) - - return prompt_embed, pooled_prompt_embed - - def encode_prompt( - self, - prompt: list[str], - negative_prompt: list[str] | None = None, - num_images_per_prompt: int = 1, - ): - clip_l_prompt_embed, clip_l_pooled_embed = self._get_prompt_embed( - prompt=prompt, - encoder_name="clip_l", - ) - prompt_embed, pooled_prompt_embed = self._duplicate_text_embed( - prompt_embed=clip_l_prompt_embed.clone(), - pooled_prompt_embed=clip_l_pooled_embed.clone(), - num_images_per_prompt=num_images_per_prompt, - batch_size=self.batch_size, - ) - - clip_g_prompt_embed, clip_g_pooled_embed = self._get_prompt_embed( - prompt=prompt, - encoder_name="clip_g", - ) - prompt_2_embed, pooled_prompt_2_embed = self._duplicate_text_embed( - prompt_embed=clip_g_prompt_embed.clone(), - pooled_prompt_embed=clip_g_pooled_embed.clone(), - batch_size=self.batch_size, - num_images_per_prompt=num_images_per_prompt, - ) - - _, t5_prompt_embed = self._get_prompt_embed( - prompt=prompt, - encoder_name="t5", - ) - - t5_prompt_embed, _ = self._duplicate_text_embed( - prompt_embed=t5_prompt_embed.clone(), - batch_size=self.batch_size, - num_images_per_prompt=num_images_per_prompt, - ) - - clip_prompt_embeds = torch.cat([prompt_embed, prompt_2_embed], dim=-1) - clip_prompt_embeds = torch.nn.functional.pad( - clip_prompt_embeds, (0, t5_prompt_embed.shape[-1] - clip_prompt_embeds.shape[-1]) - ) - prompt_embeds = torch.cat([clip_prompt_embeds, t5_prompt_embed], dim=-2) - pooled_prompt_embeds = torch.cat([pooled_prompt_embed, pooled_prompt_2_embed], dim=-1) - - if negative_prompt is None: - negative_prompt = "" - - clip_l_negative_prompt_embed, clip_l_negative_pooled_embed = self._get_prompt_embed( - prompt=negative_prompt, - encoder_name="clip_l", - ) - negative_prompt_embed, negative_pooled_prompt_embed = self._duplicate_text_embed( - prompt_embed=clip_l_negative_prompt_embed.clone(), - pooled_prompt_embed=clip_l_negative_pooled_embed.clone(), - batch_size=self.batch_size, - num_images_per_prompt=num_images_per_prompt, - ) - - clip_g_negative_prompt_embed, clip_g_negative_pooled_embed = self._get_prompt_embed( - prompt=negative_prompt, - encoder_name="clip_g", - ) - negative_prompt_2_embed, negative_pooled_prompt_2_embed = self._duplicate_text_embed( - prompt_embed=clip_g_negative_prompt_embed.clone(), - pooled_prompt_embed=clip_g_negative_pooled_embed.clone(), - batch_size=self.batch_size, - num_images_per_prompt=num_images_per_prompt, - ) - - _, t5_negative_prompt_embed = self._get_prompt_embed( - prompt=negative_prompt, - encoder_name="t5", - ) - - t5_negative_prompt_embed, _ = self._duplicate_text_embed( - prompt_embed=t5_negative_prompt_embed.clone(), - batch_size=self.batch_size, - num_images_per_prompt=num_images_per_prompt, - ) - - negative_clip_prompt_embeds = torch.cat([negative_prompt_embed, negative_prompt_2_embed], dim=-1) - negative_clip_prompt_embeds = torch.nn.functional.pad( - negative_clip_prompt_embeds, - (0, t5_negative_prompt_embed.shape[-1] - negative_clip_prompt_embeds.shape[-1]), - ) - negative_prompt_embeds = torch.cat([negative_clip_prompt_embeds, t5_negative_prompt_embed], dim=-2) - negative_pooled_prompt_embeds = torch.cat( - [negative_pooled_prompt_embed, negative_pooled_prompt_2_embed], dim=-1 - ) - - return prompt_embeds, negative_prompt_embeds, pooled_prompt_embeds, negative_pooled_prompt_embeds - - @staticmethod - def initialize_latents( - batch_size: int, - num_channels_latents: int, - latent_height: int, - latent_width: int, - device: torch.device, - generator: torch.Generator, - dtype=torch.float32, - layout=torch.strided, - ) -> torch.Tensor: - latents_shape = (batch_size, num_channels_latents, latent_height, latent_width) - latents = torch.randn( - latents_shape, - dtype=dtype, - device="cuda", - generator=generator, - layout=layout, - ).to(device) - return latents - - # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.retrieve_timesteps - @staticmethod - def retrieve_timesteps( - scheduler, - num_inference_steps: int | None = None, - device: str | torch.device | None = None, - timesteps: list[int] | None = None, - sigmas: list[float] | None = None, - **kwargs, - ): - r""" - Calls the scheduler's `set_timesteps` method and retrieves timesteps from the scheduler after the call. Handles - custom timesteps. Any kwargs will be supplied to `scheduler.set_timesteps`. - - Args: - scheduler (`SchedulerMixin`): - The scheduler to get timesteps from. - num_inference_steps (`int`): - The number of diffusion steps used when generating samples with a pre-trained model. If used, `timesteps` - must be `None`. - device (`str` or `torch.device`, *optional*): - The device to which the timesteps should be moved to. If `None`, the timesteps are not moved. - timesteps (`List[int]`, *optional*): - Custom timesteps used to override the timestep spacing strategy of the scheduler. If `timesteps` is passed, - `num_inference_steps` and `sigmas` must be `None`. - sigmas (`List[float]`, *optional*): - Custom sigmas used to override the timestep spacing strategy of the scheduler. If `sigmas` is passed, - `num_inference_steps` and `timesteps` must be `None`. - - Returns: - `Tuple[torch.Tensor, int]`: A tuple where the first element is the timestep schedule from the scheduler and the - second element is the number of inference steps. - """ - if timesteps is not None and sigmas is not None: - raise ValueError( - "Only one of `timesteps` or `sigmas` can be passed. Please choose one to set custom values" - ) - if timesteps is not None: - accepts_timesteps = "timesteps" in set(inspect.signature(scheduler.set_timesteps).parameters.keys()) - if not accepts_timesteps: - raise ValueError( - f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom" - f" timestep schedules. Please check whether you are using the correct scheduler." - ) - scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs) - timesteps = scheduler.timesteps - num_inference_steps = len(timesteps) - elif sigmas is not None: - accept_sigmas = "sigmas" in set(inspect.signature(scheduler.set_timesteps).parameters.keys()) - if not accept_sigmas: - raise ValueError( - f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom" - f" sigmas schedules. Please check whether you are using the correct scheduler." - ) - scheduler.set_timesteps(sigmas=sigmas, device=device, **kwargs) - timesteps = scheduler.timesteps - num_inference_steps = len(timesteps) - else: - scheduler.set_timesteps(num_inference_steps, device=device, **kwargs) - timesteps = scheduler.timesteps - return timesteps, num_inference_steps - - def get_control_block_samples(self, params_controlnet, controlnet_name="controlnet"): - # Predict the controlnet block samples - if self.torch_inference or self.torch_fallback[controlnet_name]: - block_samples = self.torch_models[controlnet_name](**params_controlnet) - else: - block_samples = self.run_engine(controlnet_name, params_controlnet)["controlnet_block_samples"].clone() - - return block_samples - - def denoise_latents( - self, - latents: torch.Tensor, - prompt_embeds: torch.Tensor, - pooled_prompt_embeds: torch.Tensor, - timesteps: torch.FloatTensor, - guidance_scale: float, - denoiser="transformer", - control_image=None, - controlnet_scale=None, - controlnet_keep=None, - ) -> torch.Tensor: - do_autocast = self.torch_inference != "" and self.models[denoiser].fp16 - with torch.autocast("cuda", enabled=do_autocast): - self.profile_start(denoiser, color="blue") - - for step_index, timestep in enumerate(timesteps): - # expand the latents as we are doing classifier free guidance - latents_model_input = torch.cat([latents] * 2) if self.do_classifier_free_guidance else latents - # broadcast to batch dimension in a way that's compatible with ONNX/Core ML - timestep_inp = timestep.expand(latents_model_input.shape[0]) - - controlnet_name = f"controlnet_{self.controlnet}" - if control_image is not None: - cond_scale = controlnet_scale * controlnet_keep[step_index] - - cast_to = ( - torch.float16 - if self.models[controlnet_name].fp16 - else torch.bfloat16 if self.models[controlnet_name].bf16 else torch.float32 - ) - params_controlnet = { - "hidden_states": latents_model_input, - "timestep": timestep_inp, - "pooled_projections": pooled_prompt_embeds, - "controlnet_cond": control_image, - "conditioning_scale": cond_scale.to(self.device).to(cast_to), - } - - control_block_samples = self.get_control_block_samples(params_controlnet, controlnet_name) - else: - latent_shape = latents_model_input.shape - # Initialize control block samples with zeros. Hard-coding some dimensions that can only be queried if a controlnet is used. - control_block_samples = torch.zeros( - self.models["transformer"].num_controlnet_layers, - latent_shape[0], # batch size - latent_shape[2] // 2 * latent_shape[3] // 2, - self.models["transformer"].config["num_attention_heads"] - * self.models["transformer"].config["attention_head_dim"], - dtype=latents.dtype, - device=latents.device, - ) - params = { - "hidden_states": latents_model_input, - "timestep": timestep_inp, - "encoder_hidden_states": prompt_embeds, - "pooled_projections": pooled_prompt_embeds, - "block_controlnet_hidden_states": control_block_samples, - } - - # Predict the noise residual - if self.torch_inference or self.torch_fallback[denoiser]: - noise_pred = self.torch_models[denoiser](**params)["sample"] - else: - noise_pred = self.run_engine(denoiser, params)["latent"] - - # perform guidance - if self.do_classifier_free_guidance: - noise_pred_uncond, noise_pred_text = noise_pred.chunk(2) - noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond) - - # compute the previous noisy sample x_t -> x_t-1 - latents = self.scheduler.step(noise_pred, timestep, latents, return_dict=False)[0] - - self.profile_stop(denoiser) - return latents - - def prepare_image( - self, - image, - width, - height, - device, - dtype, - ): - image = self.image_processor.preprocess(image, height=height, width=width) - - image = image.to(device=device, dtype=dtype) - - if self.do_classifier_free_guidance: - image = torch.cat([image] * 2) - - return image - - def encode_image(self, input_image, model_name="vae_encoder"): - self.profile_start(model_name, color="red") - cast_to = ( - torch.float16 - if self.models[model_name].fp16 - else torch.bfloat16 if self.models[model_name].bf16 else torch.float32 - ) - input_image = input_image.to(dtype=cast_to) - if self.torch_inference or self.torch_fallback[model_name]: - image_latents = self.torch_models[model_name](input_image) - else: - image_latents = self.run_engine(model_name, {"images": input_image})["latent"] - image_latents = (image_latents - self.models["vae"].config["shift_factor"]) * self.models[ - "vae" - ].config["scaling_factor"] - self.profile_stop(model_name) - return image_latents - - def decode_latents(self, latents: torch.Tensor, decoder="vae") -> torch.Tensor: - cast_to = ( - torch.float16 - if self.models[decoder].fp16 - else torch.bfloat16 - if self.models[decoder].bf16 - else torch.float32 - ) - latents = latents.to(dtype=cast_to) - self.profile_start(decoder, color="red") - if self.torch_inference or self.torch_fallback[decoder]: - images = self.torch_models[decoder](latents, return_dict=False)[0] - else: - images = self.run_engine(decoder, {"latent": latents})["images"] - self.profile_stop(decoder) - return images - - def infer( - self, - prompt: list[str], - negative_prompt: list[str], - image_height: int, - image_width: int, - control_image=None, - controlnet_scale=None, - control_guidance_start: Union[float, List[float]] = 0.0, - control_guidance_end: Union[float, List[float]] = 1.0, - warmup=False, - save_image=True, - ): - """ - Run the diffusion pipeline. - - Args: - prompt (list[str]): - The text prompt to guide image generation. - negative_prompt (list[str]): - The prompt not to guide the image generation. - image_height (int): - Height (in pixels) of the image to be generated. Must be a multiple of 8. - image_width (int): - Width (in pixels) of the image to be generated. Must be a multiple of 8. - control_image (PIL.Image.Image): - The control image to guide the image generation. - controlnet_scale (torch.Tensor): - A tensor which contains ControlNet scale, essential for multi ControlNet. - control_guidance_start (`float` or `List[float]`, *optional*, defaults to 0.0): - The percentage of total steps at which the ControlNet starts applying. - control_guidance_end (`float` or `List[float]`, *optional*, defaults to 1.0): - The percentage of total steps at which the ControlNet stops applying. - warmup (bool): - Indicate if this is a warmup run. - save_image (bool): - Save the generated image (if applicable) - """ - assert len(prompt) == len(negative_prompt) - self.batch_size = len(prompt) - - # Spatial dimensions of latent tensor - assert image_height % (self.vae_scale_factor * self.patch_size) == 0, ( - f"image height not supported {image_height}" - ) - assert image_width % (self.vae_scale_factor * self.patch_size) == 0, f"image width not supported {image_width}" - latent_height = int(image_height) // self.vae_scale_factor - latent_width = int(image_width) // self.vae_scale_factor - - with torch.inference_mode(), trt.Runtime(TRT_LOGGER): - torch.cuda.synchronize() - e2e_tic = time.perf_counter() - - # 1. encode inputs - with self.model_memory_manager(["clip_g", "clip_l", "t5"], low_vram=self.low_vram): - ( - prompt_embeds, - negative_prompt_embeds, - pooled_prompt_embeds, - negative_pooled_prompt_embeds, - ) = self.encode_prompt( - prompt=prompt, - negative_prompt=negative_prompt, - num_images_per_prompt=1, - ) - # do classifier free guidance - if self.do_classifier_free_guidance: - prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds], dim=0) - pooled_prompt_embeds = torch.cat([negative_pooled_prompt_embeds, pooled_prompt_embeds], dim=0) - - # 2. Prepare latent variables - num_channels_latents = self.models["transformer"].config["in_channels"] - latents = self.initialize_latents( - batch_size=self.batch_size, - num_channels_latents=num_channels_latents, - latent_height=latent_height, - latent_width=latent_width, - device=prompt_embeds.device, - generator=self.generator, - dtype=torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32, - ) - - # 3. Prepare timesteps - timesteps, num_inference_steps = self.retrieve_timesteps( - scheduler=self.scheduler, - num_inference_steps=self.denoising_steps, - device=self.device, - sigmas=None, - ) - - # 4. Prepare control image - controlnet_keep = [] - if control_image is not None: - # Process controlnet_scales - for i in range(len(timesteps)): - keeps = [ - 1.0 - float(i / len(timesteps) < s or (i + 1) / len(timesteps) > e) - for s, e in zip([control_guidance_start], [control_guidance_end]) - ] - controlnet_keep.append(keeps[0]) - - control_image = self.prepare_image( - image=control_image, - width=image_width, - height=image_height, - device=self.device, - dtype=torch.float16 if self.fp16 else torch.bfloat16 if self.bf16 else torch.float32, - ) - - with self.model_memory_manager(["vae_encoder"], low_vram=self.low_vram): - control_image = self.encode_image(control_image) - - # 5. Denoise - denoiser_list = ["transformer", f"controlnet_{self.controlnet}"] if self.controlnet else ["transformer"] - with self.model_memory_manager(denoiser_list, low_vram=self.low_vram): - latents = self.denoise_latents( - latents=latents, - prompt_embeds=prompt_embeds, - pooled_prompt_embeds=pooled_prompt_embeds, - timesteps=timesteps, - guidance_scale=self.guidance_scale, - control_image=control_image, - # TODO: support multiple controlnets - controlnet_scale=controlnet_scale, - controlnet_keep=controlnet_keep, - ) - - # 6. Decode Latents - latents = (latents / self.models["vae"].config["scaling_factor"]) + self.models["vae"].config[ - "shift_factor" - ] - with self.model_memory_manager(["vae"], low_vram=self.low_vram): - images = self.decode_latents(latents) - - torch.cuda.synchronize() - e2e_toc = time.perf_counter() - - walltime_ms = (e2e_toc - e2e_tic) * 1000.0 - if not warmup: - self.print_summary( - num_inference_steps, - walltime_ms, - ) - if save_image: - # post-process images - images = ( - ((images + 1) * 255 / 2) - .clamp(0, 255) - .detach() - .permute(0, 2, 3, 1) - .round() - .type(torch.uint8) - .cpu() - .numpy() - ) - self.save_image(images, self.pipeline_type.name.lower(), prompt, self.seed) - - return images, walltime_ms - - def run( - self, - prompt: list[str], - negative_prompt: list[str], - height: int, - width: int, - batch_count: int, - num_warmup_runs: int, - use_cuda_graph: bool, - **kwargs, - ): - num_warmup_runs = max(1, num_warmup_runs) if use_cuda_graph else num_warmup_runs - if num_warmup_runs > 0: - print("[I] Warming up ..") - for _ in range(num_warmup_runs): - self.infer(prompt, negative_prompt, height, width, warmup=True, **kwargs) - - for _ in range(batch_count): - print("[I] Running StableDiffusion 3.5 pipeline") - if self.nvtx_profile: - cudart.cudaProfilerStart() - self.infer(prompt, negative_prompt, height, width, warmup=False, **kwargs) - if self.nvtx_profile: - cudart.cudaProfilerStop() diff --git a/demo/Diffusion/demo_diffusion/pipeline/stable_diffusion_3_pipeline.py b/demo/Diffusion/demo_diffusion/pipeline/stable_diffusion_3_pipeline.py deleted file mode 100644 index 88340a407..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/stable_diffusion_3_pipeline.py +++ /dev/null @@ -1,599 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import math -import os -import pathlib -import time - -import nvtx -import tensorrt as trt -import torch -from cuda.bindings import runtime as cudart - -import demo_diffusion.engine as engine_module -import demo_diffusion.image as image_module -from demo_diffusion.model import ( - SD3_CLIPGModel, - SD3_CLIPLModel, - SD3_MMDiTModel, - SD3_T5XXLModel, - SD3_VAEDecoderModel, - SD3_VAEEncoderModel, - get_clip_embedding_dim, -) -from demo_diffusion.pipeline.type import PIPELINE_TYPE -from demo_diffusion.utils_sd3.other_impls import SD3Tokenizer -from demo_diffusion.utils_sd3.sd3_impls import SD3LatentFormat, sample_euler - -TRT_LOGGER = trt.Logger(trt.Logger.ERROR) - - -class StableDiffusion3Pipeline: - """ - Application showcasing the acceleration of Stable Diffusion 3 pipelines using NVidia TensorRT. - """ - def __init__( - self, - version='sd3', - pipeline_type=PIPELINE_TYPE.TXT2IMG, - max_batch_size=16, - shift=1.0, - cfg_scale=5, - denoising_steps=50, - denoising_percentage=0.6, - input_image=None, - device='cuda', - output_dir='.', - hf_token=None, - verbose=False, - nvtx_profile=False, - use_cuda_graph=False, - framework_model_dir='pytorch_model', - torch_inference='', - ): - """ - Initializes the Stable Diffusion 3 pipeline. - - Args: - version (str): - The version of the pipeline. Should be one of ['sd3] - pipeline_type (PIPELINE_TYPE): - Type of current pipeline. - max_batch_size (int): - Maximum batch size for dynamic batch engine. - shift (float): - Shift parameter for MMDiT model. Default: 1.0 - cfg_scale (int): - CFG Scale used for denoising. Default: 5 - denoising_steps (int): - Number of denoising steps. Default: 1.0 - denoising_percentage (float): - Denoising percentage. Default: 0.6 - input_image (float): - Input image for conditioning. Default: None - device (str): - PyTorch device to run inference. Default: 'cuda' - output_dir (str): - Output directory for log files and image artifacts - hf_token (str): - HuggingFace User Access Token to use for downloading Stable Diffusion model checkpoints. - verbose (bool): - Enable verbose logging. - nvtx_profile (bool): - Insert NVTX profiling markers. - use_cuda_graph (bool): - Use CUDA graph to capture engine execution and then launch inference - framework_model_dir (str): - cache directory for framework checkpoints - torch_inference (str): - Run inference with PyTorch (using specified compilation mode) instead of TensorRT. - """ - - self.max_batch_size = max_batch_size - self.shift = shift - self.cfg_scale = cfg_scale - self.denoising_steps = denoising_steps - self.input_image = input_image - self.denoising_percentage = denoising_percentage if input_image is not None else 1.0 - - self.framework_model_dir = framework_model_dir - self.output_dir = output_dir - for directory in [self.framework_model_dir, self.output_dir]: - if not os.path.exists(directory): - print(f"[I] Create directory: {directory}") - pathlib.Path(directory).mkdir(parents=True) - - self.hf_token = hf_token - self.device = device - self.verbose = verbose - self.nvtx_profile = nvtx_profile - - self.version = version - - # Pipeline type - self.pipeline_type = pipeline_type - self.stages = ['clip_g', 'clip_l', 't5xxl', 'transformer', 'vae_decoder'] - if input_image is not None: - self.stages = ['vae_encoder'] + self.stages - - self.config = {} - self.config['clip_hidden_states'] = True - self.config['t5xxl_torch_fallback'] = True - self.config['vae_encoder_torch_fallback'] = True - self.torch_inference = torch_inference - if self.torch_inference: - torch._inductor.config.conv_1x1_as_mm = True - torch._inductor.config.coordinate_descent_tuning = True - torch._inductor.config.epilogue_fusion = False - torch._inductor.config.coordinate_descent_check_all_directions = True - self.use_cuda_graph = use_cuda_graph - - # initialized in loadEngines() - self.models = {} - self.torch_models = {} - self.engine = {} - self.shared_device_memory = None - - # initialized in loadResources() - self.events = {} - self.generator = None - self.markers = {} - self.seed = None - self.stream = None - self.tokenizer = None - - def loadResources(self, image_height, image_width, batch_size, seed): - # Initialize noise generator - if seed: - self.seed = seed - self.generator = torch.Generator(device="cuda").manual_seed(seed) - - # Create CUDA events and stream - for stage in self.stages: - self.events[stage] = [cudart.cudaEventCreate()[1], cudart.cudaEventCreate()[1]] - self.stream = cudart.cudaStreamCreate()[1] - - # Allocate TensorRT I/O buffers - if not self.torch_inference: - for model_name, obj in self.models.items(): - if self.torch_fallback[model_name]: - continue - self.engine[model_name].allocate_buffers(shape_dict=obj.get_shape_dict(batch_size, image_height, image_width), device=self.device) - - def teardown(self): - for e in self.events.values(): - cudart.cudaEventDestroy(e[0]) - cudart.cudaEventDestroy(e[1]) - - for engine in self.engine.values(): - del engine - - if self.shared_device_memory: - cudart.cudaFree(self.shared_device_memory) - - cudart.cudaStreamDestroy(self.stream) - del self.stream - - def getOnnxPath(self, model_name, onnx_dir, opt=True, suffix=''): - onnx_model_dir = os.path.join(onnx_dir, model_name+suffix+('.opt' if opt else '')) - os.makedirs(onnx_model_dir, exist_ok=True) - return os.path.join(onnx_model_dir, 'model.onnx') - - def getEnginePath(self, model_name, engine_dir, enable_refit=False, suffix=''): - return os.path.join(engine_dir, model_name+suffix+('.refit' if enable_refit else '')+'.trt'+trt.__version__+'.plan') - - def loadEngines( - self, - engine_dir, - framework_model_dir, - onnx_dir, - onnx_opset, - opt_batch_size, - opt_image_height, - opt_image_width, - static_batch=False, - static_shape=True, - enable_all_tactics=False, - timing_cache=None, - **_kwargs, - ): - """ - Build and load engines for TensorRT accelerated inference. - Export ONNX models first, if applicable. - - Args: - engine_dir (str): - Directory to store the TensorRT engines. - framework_model_dir (str): - Directory to store the framework model ckpt. - onnx_dir (str): - Directory to store the ONNX models. - onnx_opset (int): - ONNX opset version to export the models. - opt_batch_size (int): - Batch size to optimize for during engine building. - opt_image_height (int): - Image height to optimize for during engine building. Must be a multiple of 8. - opt_image_width (int): - Image width to optimize for during engine building. Must be a multiple of 8. - static_batch (bool): - Build engine only for specified opt_batch_size. - static_shape (bool): - Build engine only for specified opt_image_height & opt_image_width. Default = True. - enable_all_tactics (bool): - Enable all tactic sources during TensorRT engine builds. - timing_cache (str): - Path to the timing cache to speed up TensorRT build. - """ - # Create directories if missing - for directory in [engine_dir, onnx_dir]: - if not os.path.exists(directory): - print(f"[I] Create directory: {directory}") - pathlib.Path(directory).mkdir(parents=True) - - # Load pipeline models - models_args = {'version': self.version, 'pipeline': self.pipeline_type, 'device': self.device, - 'hf_token': self.hf_token, 'verbose': self.verbose, 'framework_model_dir': framework_model_dir, - 'max_batch_size': self.max_batch_size} - - # Load text tokenizer - self.tokenizer = SD3Tokenizer() - - # Load text encoders - if 'clip_g' in self.stages: - self.models['clip_g'] = SD3_CLIPGModel(**models_args, fp16=True, pooled_output=True) - - if 'clip_l' in self.stages: - self.models['clip_l'] = SD3_CLIPLModel(**models_args, fp16=True, pooled_output=True) - - if 't5xxl' in self.stages: - self.models['t5xxl'] = SD3_T5XXLModel(**models_args, fp16=True, embedding_dim=get_clip_embedding_dim(self.version, self.pipeline_type)) - - # Load Transformer model - if 'transformer' in self.stages: - self.models['transformer'] = SD3_MMDiTModel(**models_args, fp16=True, shift=self.shift) - - # Load VAE Encoder model - if 'vae_encoder' in self.stages: - self.models['vae_encoder'] = SD3_VAEEncoderModel(**models_args, fp16=True) - - # Load VAE Decoder model - if 'vae_decoder' in self.stages: - self.models['vae_decoder'] = SD3_VAEDecoderModel(**models_args, fp16=True) - - # Configure pipeline models to load - model_names = self.models.keys() - # Torch fallback - self.torch_fallback = dict(zip(model_names, [self.torch_inference or self.config.get(model_name.replace('-','_')+'_torch_fallback', False) for model_name in model_names])) - - onnx_path = dict(zip(model_names, [self.getOnnxPath(model_name, onnx_dir, opt=False) for model_name in model_names])) - onnx_opt_path = dict(zip(model_names, [self.getOnnxPath(model_name, onnx_dir) for model_name in model_names])) - engine_path = dict(zip(model_names, [self.getEnginePath(model_name, engine_dir) for model_name in model_names])) - - for model_name, obj in self.models.items(): - if self.torch_fallback[model_name]: - continue - # Export models to ONNX - do_export_onnx = not os.path.exists(engine_path[model_name]) and not os.path.exists(onnx_opt_path[model_name]) - if do_export_onnx: - obj.export_onnx(onnx_path[model_name], onnx_opt_path[model_name], onnx_opset, opt_image_height, opt_image_width, static_shape=static_shape) - - # Build TensorRT engines - for model_name, obj in self.models.items(): - if self.torch_fallback[model_name]: - continue - engine = engine_module.Engine(engine_path[model_name]) - if not os.path.exists(engine_path[model_name]): - update_output_names = obj.get_output_names() + obj.extra_output_names if obj.extra_output_names else None - extra_build_args = {'verbose': self.verbose} - engine.build(onnx_opt_path[model_name], - input_profile=obj.get_input_profile( - opt_batch_size, opt_image_height, opt_image_width, - static_batch=static_batch, static_shape=static_shape - ), - enable_all_tactics=enable_all_tactics, - timing_cache=timing_cache, - update_output_names=update_output_names, - verbose=self.verbose - ) - self.engine[model_name] = engine - - # Load TensorRT engines - for model_name, obj in self.models.items(): - if self.torch_fallback[model_name]: - continue - self.engine[model_name].load() - - # Load torch models - for model_name, obj in self.models.items(): - if self.torch_fallback[model_name] or model_name == 'transformer': - self.torch_models[model_name] = obj.get_model(torch_inference=self.torch_inference) - - def calculateMaxDeviceMemory(self): - max_device_memory = 0 - for model_name, engine in self.engine.items(): - max_device_memory = max(max_device_memory, engine.engine.device_memory_size_v2) - return max_device_memory - - def activateEngines(self, shared_device_memory=None): - if shared_device_memory is None: - max_device_memory = self.calculateMaxDeviceMemory() - _, shared_device_memory = cudart.cudaMalloc(max_device_memory) - self.shared_device_memory = shared_device_memory - # Load and activate TensorRT engines - for engine in self.engine.values(): - engine.activate(device_memory=self.shared_device_memory) - - def runEngine(self, model_name, feed_dict): - engine = self.engine[model_name] - return engine.infer(feed_dict, self.stream, use_cuda_graph=self.use_cuda_graph) - - def initialize_latents(self, batch_size, unet_channels, latent_height, latent_width): - return torch.ones(batch_size, unet_channels, latent_height, latent_width, device="cuda") * 0.0609 - - def profile_start(self, name, color='blue'): - if self.nvtx_profile: - self.markers[name] = nvtx.start_range(message=name, color=color) - if name in self.events: - cudart.cudaEventRecord(self.events[name][0], 0) - - def profile_stop(self, name): - if name in self.events: - cudart.cudaEventRecord(self.events[name][1], 0) - if self.nvtx_profile: - nvtx.end_range(self.markers[name]) - - def print_summary(self, denoising_steps, walltime_ms, batch_size): - print('|-----------------|--------------|') - print('| {:^15} | {:^12} |'.format('Module', 'Latency')) - print('|-----------------|--------------|') - for stage in self.stages: - stage_name = stage - if "transformer" in stage: - stage_name += ' x ' + str(denoising_steps) - print( - "| {:^15} | {:>9.2f} ms |".format( - stage_name, cudart.cudaEventElapsedTime(self.events[stage][0], self.events[stage][1])[1], - ) - ) - print('|-----------------|--------------|') - print('| {:^15} | {:>9.2f} ms |'.format('Pipeline', walltime_ms)) - print('|-----------------|--------------|') - print('Throughput: {:.5f} image/s'.format(batch_size*1000./walltime_ms)) - - def save_image(self, images, pipeline, prompt, seed): - # Save image - image_name_prefix = pipeline+''.join(set(['-'+prompt[i].replace(' ','_')[:10] for i in range(len(prompt))]))+'-'+str(seed)+'-' - image_name_suffix = 'torch' if self.torch_inference else 'trt' - image_module.save_image(images, self.output_dir, image_name_prefix, image_name_suffix) - - def encode_prompt(self, prompt, negative_prompt): - def encode_token_weights(model_name, token_weight_pairs): - self.profile_start(model_name, color='green') - - tokens = list(map(lambda a: a[0], token_weight_pairs[0])) - tokens = torch.tensor([tokens], dtype=torch.int64, device=self.device) - if self.torch_inference or self.torch_fallback[model_name]: - out, pooled = self.torch_models[model_name](tokens) - else: - trt_out = self.runEngine(model_name, {'input_ids': tokens}) - out, pooled = trt_out['text_embeddings'], trt_out["pooled_output"] - - self.profile_stop(model_name) - - if pooled is not None: - first_pooled = pooled[0:1].cuda() - else: - first_pooled = pooled - output = [out[0:1]] - return torch.cat(output, dim=-2).cuda(), first_pooled - - def tokenize(prompt): - tokens = self.tokenizer.tokenize_with_weights(prompt) - l_out, l_pooled = encode_token_weights('clip_l', tokens["l"]) - g_out, g_pooled = encode_token_weights('clip_g', tokens["g"]) - t5_out, _ = encode_token_weights('t5xxl', tokens["t5xxl"]) - lg_out = torch.cat([l_out, g_out], dim=-1) - lg_out = torch.nn.functional.pad(lg_out, (0, 4096 - lg_out.shape[-1])) - - return torch.cat([lg_out, t5_out], dim=-2), torch.cat((l_pooled, g_pooled), dim=-1) - - conditioning = tokenize(prompt[0]) - neg_conditioning = tokenize(negative_prompt[0]) - return conditioning, neg_conditioning - - def denoise_latent(self, latent, conditioning, neg_conditioning, model_name='transformer'): - def get_noise(latent): - return torch.randn(latent.size(), dtype=torch.float32, layout=latent.layout, generator=self.generator, device="cuda").to(latent.dtype) - - def get_sigmas(sampling, steps): - start = sampling.timestep(sampling.sigma_max) - end = sampling.timestep(sampling.sigma_min) - timesteps = torch.linspace(start, end, steps) - sigs = [] - for x in range(len(timesteps)): - ts = timesteps[x] - sigs.append(sampling.sigma(ts)) - sigs += [0.0] - return torch.FloatTensor(sigs) - - def max_denoise(sigmas): - max_sigma = float(self.torch_models[model_name].model_sampling.sigma_max) - sigma = float(sigmas[0]) - return math.isclose(max_sigma, sigma, rel_tol=1e-05) or sigma > max_sigma - - def fix_cond(cond): - cond, pooled = (cond[0].half().cuda(), cond[1].half().cuda()) - return { "c_crossattn": cond, "y": pooled } - - def cfg_denoiser(x, timestep, cond, uncond, cond_scale): - # Run cond and uncond in a batch together - sample = torch.cat([x, x]) - sigma = torch.cat([timestep, timestep]) - c_crossattn = torch.cat([cond["c_crossattn"], uncond["c_crossattn"]]) - y = torch.cat([cond["y"], uncond["y"]]) - if self.torch_inference or self.torch_fallback[model_name]: - with torch.autocast("cuda", dtype=torch.float16): - batched = self.torch_models[model_name](sample, sigma, c_crossattn=c_crossattn, y=y) - else: - input_dict = {'sample': sample, 'sigma': sigma, 'c_crossattn': c_crossattn, 'y': y} - batched = self.runEngine(model_name, input_dict)['latent'] - - # Then split and apply CFG Scaling - pos_out, neg_out = batched.chunk(2) - scaled = neg_out + (pos_out - neg_out) * cond_scale - return scaled - - self.profile_start(model_name, color='blue') - - latent = latent.half().cuda() - noise = get_noise(latent).cuda() - sigmas = get_sigmas(self.torch_models[model_name].model_sampling, self.denoising_steps).cuda() - sigmas = sigmas[int(self.denoising_steps * (1 - self.denoising_percentage)):] - conditioning = fix_cond(conditioning) - neg_conditioning = fix_cond(neg_conditioning) - - noise_scaled = self.torch_models[model_name].model_sampling.noise_scaling(sigmas[0], noise, latent, max_denoise(sigmas)) - extra_args = { "cond": conditioning, "uncond": neg_conditioning, "cond_scale": self.cfg_scale } - latent = sample_euler(cfg_denoiser, noise_scaled, sigmas, extra_args=extra_args) - latent = SD3LatentFormat().process_out(latent) - - self.profile_stop(model_name) - - return latent - - def encode_image(self, model_name='vae_encoder'): - self.input_image = self.input_image.to(self.device) - self.profile_start(model_name, color='orange') - if self.torch_inference or self.torch_fallback[model_name]: - with torch.autocast("cuda", dtype=torch.float16): - latent = self.torch_models[model_name](self.input_image) - else: - latent = self.runEngine(model_name, {'images': self.input_image})['latent'] - - latent = SD3LatentFormat().process_in(latent) - self.profile_stop(model_name) - return latent - - def decode_latent(self, latent, model_name='vae_decoder'): - self.profile_start(model_name, color='red') - if self.torch_inference or self.torch_fallback[model_name]: - with torch.autocast("cuda", dtype=torch.float16): - image = self.torch_models[model_name](latent) - else: - image = self.runEngine(model_name, {'latent': latent})['images'] - image = image.float() - self.profile_stop(model_name) - return image - - def infer( - self, - prompt, - negative_prompt, - image_height, - image_width, - warmup=False, - save_image=True, - ): - """ - Run the diffusion pipeline. - - Args: - prompt (str): - The text prompt to guide image generation. - negative_prompt (str): - The prompt not to guide the image generation. - image_height (int): - Height (in pixels) of the image to be generated. Must be a multiple of 8. - image_width (int): - Width (in pixels) of the image to be generated. Must be a multiple of 8. - warmup (bool): - Indicate if this is a warmup run. - save_image (bool): - Save the generated image (if applicable) - """ - assert len(prompt) == len(negative_prompt) - batch_size = len(prompt) - - # Spatial dimensions of latent tensor - latent_height = image_height // 8 - latent_width = image_width // 8 - - if self.generator and self.seed: - self.generator.manual_seed(self.seed) - - with torch.inference_mode(), trt.Runtime(TRT_LOGGER): - torch.cuda.synchronize() - e2e_tic = time.perf_counter() - - # Initialize Latents - latent = self.initialize_latents(batch_size=batch_size, - unet_channels=16, - latent_height=latent_height, - latent_width=latent_width) - - # Encode input image - if self.input_image is not None: - latent = self.encode_image() - - # Get Conditionings - conditioning, neg_conditioning = self.encode_prompt(prompt, negative_prompt) - - # Denoise - latent = self.denoise_latent(latent, conditioning, neg_conditioning) - - # Decode Latents - images = self.decode_latent(latent) - - torch.cuda.synchronize() - e2e_toc = time.perf_counter() - - walltime_ms = (e2e_toc - e2e_tic) * 1000. - if not warmup: - num_inference_steps = int(self.denoising_steps * self.denoising_percentage) - self.print_summary(num_inference_steps, walltime_ms, batch_size) - if save_image: - # post-process images - images = ((images + 1) * 255 / 2).clamp(0, 255).detach().permute(0, 2, 3, 1).round().type(torch.uint8).cpu().numpy() - self.save_image(images, self.pipeline_type.name.lower(), prompt, self.seed) - - return images, walltime_ms - - def run(self, prompt, negative_prompt, height, width, batch_size, batch_count, num_warmup_runs, use_cuda_graph, **kwargs): - # Process prompt - if not isinstance(prompt, list): - raise ValueError(f"`prompt` must be of type `str` list, but is {type(prompt)}") - prompt = prompt * batch_size - - if not isinstance(negative_prompt, list): - raise ValueError(f"`--negative-prompt` must be of type `str` list, but is {type(negative_prompt)}") - if len(negative_prompt) == 1: - negative_prompt = negative_prompt * batch_size - - num_warmup_runs = max(1, num_warmup_runs) if use_cuda_graph else num_warmup_runs - if num_warmup_runs > 0: - print("[I] Warming up ..") - for _ in range(num_warmup_runs): - self.infer(prompt, negative_prompt, height, width, warmup=True, **kwargs) - - for _ in range(batch_count): - print("[I] Running StableDiffusion3 pipeline") - if self.nvtx_profile: - cudart.cudaProfilerStart() - self.infer(prompt, negative_prompt, height, width, warmup=False, **kwargs) - if self.nvtx_profile: - cudart.cudaProfilerStop() diff --git a/demo/Diffusion/demo_diffusion/pipeline/stable_diffusion_pipeline.py b/demo/Diffusion/demo_diffusion/pipeline/stable_diffusion_pipeline.py deleted file mode 100644 index c4d7d0cc6..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/stable_diffusion_pipeline.py +++ /dev/null @@ -1,1101 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import gc -import inspect -import json -import os -import pathlib -import sys -import time -from hashlib import md5 -from typing import List, Optional - -import modelopt.torch.opt as mto -import modelopt.torch.quantization as mtq -import numpy as np -import nvtx -import tensorrt as trt -import torch -from cuda.bindings import runtime as cudart -from diffusers import ( - DDIMScheduler, - DDPMScheduler, - DDPMWuerstchenScheduler, - EulerAncestralDiscreteScheduler, - EulerDiscreteScheduler, - LCMScheduler, - LMSDiscreteScheduler, - PNDMScheduler, - UniPCMultistepScheduler, -) - -import demo_diffusion.engine as engine_module -import demo_diffusion.image as image_module -from demo_diffusion.model import ( - CLIPModel, - CLIPWithProjModel, - SDLoraLoader, - UNet2DConditionControlNetModel, - UNetModel, - UNetXLModel, - UNetXLModelControlNet, - VAEEncoderModel, - VAEModel, - get_clip_embedding_dim, - make_scheduler, - make_tokenizer, - merge_loras, - unload_torch_model, -) -from demo_diffusion.pipeline.calibrate import load_calib_prompts -from demo_diffusion.pipeline.type import PIPELINE_TYPE -from demo_diffusion.utils_modelopt import ( - SD_FP8_FP16_DEFAULT_CONFIG, - SD_FP8_FP32_DEFAULT_CONFIG, - check_lora, - filter_func, - generate_fp8_scales, - get_int8_config, - quantize_lvl, - set_fmha, -) - -TRT_LOGGER = trt.Logger(trt.Logger.ERROR) - - -class StableDiffusionPipeline: - SCHEDULER_DEFAULTS = { - "1.4": "PNDM", - "dreamshaper-7": "PNDM", - "xl-1.0" : "Euler", - "xl-turbo": "EulerA", - "svd-xt-1.1": "Euler", - "cascade": "DDPMWuerstchen" - } - """ - Application showcasing the acceleration of Stable Diffusion pipelines using NVidia TensorRT. - """ - def __init__( - self, - version='1.4', - pipeline_type=PIPELINE_TYPE.TXT2IMG, - max_batch_size=16, - denoising_steps=30, - scheduler=None, - guidance_scale=7.5, - device='cuda', - output_dir='.', - hf_token=None, - verbose=False, - nvtx_profile=False, - use_cuda_graph=False, - vae_scaling_factor=0.18215, - framework_model_dir='pytorch_model', - controlnets=None, - lora_scale: float = 1.0, - lora_weight: Optional[List[float]] = None, - lora_path: Optional[List[str]] = None, - return_latents=False, - torch_inference='', - ): - """ - Initializes the Diffusion pipeline. - - Args: - version (str): - The version of the pipeline. Should be one of [1.4, SDXL] - pipeline_type (PIPELINE_TYPE): - Type of current pipeline. - max_batch_size (int): - Maximum batch size for dynamic batch engine. - denoising_steps (int): - The number of denoising steps. - More denoising steps usually lead to a higher quality image at the expense of slower inference. - scheduler (str): - The scheduler to guide the denoising process. Must be one of [DDIM, DPM, EulerA, Euler, LCM, LMSD, PNDM]. - guidance_scale (float): - Guidance scale is enabled by setting as > 1. - Higher guidance scale encourages to generate images that are closely linked to the text prompt, usually at the expense of lower image quality. - device (str): - PyTorch device to run inference. Default: 'cuda' - output_dir (str): - Output directory for log files and image artifacts - hf_token (str): - HuggingFace User Access Token to use for downloading Stable Diffusion model checkpoints. - verbose (bool): - Enable verbose logging. - nvtx_profile (bool): - Insert NVTX profiling markers. - use_cuda_graph (bool): - Use CUDA graph to capture engine execution and then launch inference - vae_scaling_factor (float): - VAE scaling factor - framework_model_dir (str): - cache directory for framework checkpoints - controlnets (str): - Which ControlNet/ControlNets to use. - return_latents (bool): - Skip decoding the image and return latents instead. - torch_inference (str): - Run inference with PyTorch (using specified compilation mode) instead of TensorRT. - """ - - self.denoising_steps = denoising_steps - self.guidance_scale = guidance_scale - self.do_classifier_free_guidance = (guidance_scale > 1.0) - self.vae_scaling_factor = vae_scaling_factor - - self.max_batch_size = max_batch_size - - self.framework_model_dir = framework_model_dir - self.output_dir = output_dir - for directory in [self.framework_model_dir, self.output_dir]: - if not os.path.exists(directory): - print(f"[I] Create directory: {directory}") - pathlib.Path(directory).mkdir(parents=True) - - self.hf_token = hf_token - self.device = device - self.verbose = verbose - self.nvtx_profile = nvtx_profile - - self.version = version - self.controlnets = controlnets - - # Pipeline type - self.pipeline_type = pipeline_type - if self.pipeline_type.is_txt2img(): - self.stages = ['clip','unet','vae'] - elif self.pipeline_type.is_img2img(): - self.stages = ['vae_encoder', 'clip','unet','vae'] - elif self.pipeline_type.is_sd_xl_base(): - self.stages = ['clip', 'clip2', 'unetxl'] - if not return_latents: - self.stages.append('vae') - elif self.pipeline_type.is_sd_xl_refiner(): - self.stages = ['clip2', 'unetxl', 'vae'] - elif self.pipeline_type.is_img2vid(): - self.stages = ['clip-vis', 'clip-imgfe', 'unet-temp', 'vae-temp'] - elif self.pipeline_type.is_cascade_prior(): - self.stages = ['clip', 'unet'] - elif self.pipeline_type.is_cascade_decoder(): - self.stages = ['clip', 'unet', 'vqgan'] - else: - raise ValueError(f"Unsupported pipeline {self.pipeline_type.name}.") - self.return_latents = return_latents - - if not scheduler: - scheduler = 'UniPC' if self.pipeline_type.is_controlnet() else self.SCHEDULER_DEFAULTS.get(version, 'DDIM') - print(f"[I] Autoselected scheduler: {scheduler}") - - scheduler_class_map = { - "DDIM" : DDIMScheduler, - "DDPM" : DDPMScheduler, - "EulerA" : EulerAncestralDiscreteScheduler, - "Euler" : EulerDiscreteScheduler, - "LCM" : LCMScheduler, - "LMSD" : LMSDiscreteScheduler, - "PNDM" : PNDMScheduler, - "UniPC" : UniPCMultistepScheduler, - "DDPMWuerstchen" : DDPMWuerstchenScheduler, - } - try: - scheduler_class = scheduler_class_map[scheduler] - except KeyError: - raise ValueError(f"Unsupported scheduler {scheduler}. Should be one of {list(scheduler_class.keys())}.") - self.scheduler = make_scheduler(scheduler_class, version, pipeline_type, hf_token, framework_model_dir) - - self.config = {} - if self.pipeline_type.is_sd_xl(): - self.config['clip_hidden_states'] = True - self.torch_inference = torch_inference - if self.torch_inference: - torch._inductor.config.conv_1x1_as_mm = True - torch._inductor.config.coordinate_descent_tuning = True - torch._inductor.config.epilogue_fusion = False - torch._inductor.config.coordinate_descent_check_all_directions = True - self.use_cuda_graph = use_cuda_graph - - # initialized in loadEngines() - self.models = {} - self.torch_models = {} - self.engine = {} - self.shared_device_memory = None - - # initialize lora loader and scales - self.lora_loader = None - self.lora_weights = dict() - if lora_path: - self.lora_loader = SDLoraLoader(lora_path, lora_weight, lora_scale) - assert len(lora_path) == len(lora_weight) - for i, path in enumerate(lora_path): - self.lora_weights[path] = lora_weight[i] - - # initialized in loadResources() - self.events = {} - self.generator = None - self.markers = {} - self.seed = None - self.stream = None - self.tokenizer = None - - def loadResources(self, image_height, image_width, batch_size, seed): - # Initialize noise generator - if seed: - self.seed = seed - self.generator = torch.Generator(device="cuda").manual_seed(seed) - - # Create CUDA events and stream - for stage in self.stages: - self.events[stage] = [cudart.cudaEventCreate()[1], cudart.cudaEventCreate()[1]] - self.stream = cudart.cudaStreamCreate()[1] - - # Allocate TensorRT I/O buffers - if not self.torch_inference: - for model_name, obj in self.models.items(): - self.engine[model_name].allocate_buffers(shape_dict=obj.get_shape_dict(batch_size, image_height, image_width), device=self.device) - - def teardown(self): - for e in self.events.values(): - cudart.cudaEventDestroy(e[0]) - cudart.cudaEventDestroy(e[1]) - - for engine in self.engine.values(): - del engine - - if self.shared_device_memory: - cudart.cudaFree(self.shared_device_memory) - - for torch_model in self.torch_models.values(): - del torch_model - - cudart.cudaStreamDestroy(self.stream) - del self.stream - - def cachedModelName(self, model_name): - return model_name - - def getOnnxPath(self, model_name, onnx_dir, opt=True, suffix=''): - onnx_model_dir = os.path.join(onnx_dir, self.cachedModelName(model_name)+suffix+('.opt' if opt else '')) - os.makedirs(onnx_model_dir, exist_ok=True) - return os.path.join(onnx_model_dir, 'model.onnx') - - def getEnginePath(self, model_name, engine_dir, enable_refit=False, suffix=''): - return os.path.join(engine_dir, self.cachedModelName(model_name)+suffix+('.refit' if enable_refit else '')+'.trt'+trt.__version__+'.plan') - - def getWeightsMapPath(self, model_name, onnx_dir): - onnx_model_dir = os.path.join(onnx_dir, self.cachedModelName(model_name)+'.opt') - os.makedirs(onnx_model_dir, exist_ok=True) - return os.path.join(onnx_model_dir, 'weights_map.json') - - def getRefitNodesPath(self, model_name, onnx_dir, suffix=''): - onnx_model_dir = os.path.join(onnx_dir, self.cachedModelName(model_name)+'.opt') - os.makedirs(onnx_model_dir, exist_ok=True) - return os.path.join(onnx_model_dir, 'refit'+suffix+'.json') - - def getStateDictPath(self, model_name, onnx_dir, suffix=''): - onnx_model_dir = os.path.join(onnx_dir, self.cachedModelName(model_name)+suffix) - os.makedirs(onnx_model_dir, exist_ok=True) - return os.path.join(onnx_model_dir, 'state_dict.pt') - - def initializeModels(self, framework_model_dir, int8, fp8): - # Load text tokenizer(s) - if not self.pipeline_type.is_sd_xl_refiner(): - self.tokenizer = make_tokenizer(self.version, self.pipeline_type, self.hf_token, framework_model_dir) - if self.pipeline_type.is_sd_xl(): - self.tokenizer2 = make_tokenizer(self.version, self.pipeline_type, self.hf_token, framework_model_dir, subfolder='tokenizer_2') - - # Load pipeline models - models_args = {'version': self.version, 'pipeline': self.pipeline_type, 'device': self.device, - 'hf_token': self.hf_token, 'verbose': self.verbose, 'framework_model_dir': framework_model_dir, - 'max_batch_size': self.max_batch_size} - - if 'clip' in self.stages: - subfolder = 'text_encoder' - self.models['clip'] = CLIPModel(**models_args, fp16=True, embedding_dim=get_clip_embedding_dim(self.version, self.pipeline_type), output_hidden_states=self.config.get('clip_hidden_states', False), subfolder=subfolder) - - if 'clip2' in self.stages: - subfolder = 'text_encoder_2' - self.models['clip2'] = CLIPWithProjModel(**models_args, fp16=True, output_hidden_states=self.config.get('clip_hidden_states', False), subfolder=subfolder) - - if 'unet' in self.stages: - self.models['unet'] = UNetModel(**models_args, fp16=True, int8=int8, fp8=fp8, controlnets=self.controlnets, do_classifier_free_guidance=self.do_classifier_free_guidance) - - if 'unetxl' in self.stages: - if not self.controlnets: - self.models["unetxl"] = UNetXLModel( - **models_args, - fp16=True, - int8=int8, - fp8=fp8, - do_classifier_free_guidance=self.do_classifier_free_guidance, - ) - else: - self.models["unetxl"] = UNetXLModelControlNet( - **models_args, - fp16=True, - int8=int8, - fp8=fp8, - controlnets=self.controlnets, - do_classifier_free_guidance=self.do_classifier_free_guidance, - ) - - vae_fp16 = not self.pipeline_type.is_sd_xl() - - if 'vae' in self.stages: - self.models['vae'] = VAEModel(**models_args, fp16=vae_fp16, tf32=True) - - if 'vae_encoder' in self.stages: - self.models['vae_encoder'] = VAEEncoderModel(**models_args, fp16=vae_fp16) - - def loadEngines( - self, - engine_dir, - framework_model_dir, - onnx_dir, - onnx_opset, - opt_batch_size, - opt_image_height, - opt_image_width, - optimization_level=3, - static_batch=False, - static_shape=True, - enable_refit=False, - enable_all_tactics=False, - timing_cache=None, - int8=False, - fp8=False, - quantization_level=2.5, - quantization_percentile=1.0, - quantization_alpha=0.8, - calibration_size=32, - calib_batch_size=2, - **_kwargs, - ): - """ - Build and load engines for TensorRT accelerated inference. - Export ONNX models first, if applicable. - - Args: - engine_dir (str): - Directory to store the TensorRT engines. - framework_model_dir (str): - Directory to store the framework model ckpt. - onnx_dir (str): - Directory to store the ONNX models. - onnx_opset (int): - ONNX opset version to export the models. - opt_batch_size (int): - Batch size to optimize for during engine building. - opt_image_height (int): - Image height to optimize for during engine building. Must be a multiple of 8. - opt_image_width (int): - Image width to optimize for during engine building. Must be a multiple of 8. - optimization_level (int): - Optimization level to build the TensorRT engine with. - static_batch (bool): - Build engine only for specified opt_batch_size. - static_shape (bool): - Build engine only for specified opt_image_height & opt_image_width. Default = True. - enable_refit (bool): - Build engines with refit option enabled. - enable_all_tactics (bool): - Enable all tactic sources during TensorRT engine builds. - timing_cache (str): - Path to the timing cache to speed up TensorRT build. - int8 (bool): - Whether to quantize to int8 format or not (SDXL, SD15 and SD21 only). - fp8 (bool): - Whether to quantize to fp8 format or not (SDXL, SD15 and SD21 only). - quantization_level (float): - Controls which layers to quantize. 1: CNN, 2: CNN+FFN, 2.5: CNN+FFN+QKV, 3: CNN+FC - quantization_percentile (float): - Control quantization scaling factors (amax) collecting range, where the minimum amax in - range(n_steps * percentile) will be collected. Recommendation: 1.0 - quantization_alpha (float): - The alpha parameter for SmoothQuant quantization used for linear layers. - Recommendation: 0.8 for SDXL - calibration_size (int): - The number of steps to use for calibrating the model for quantization. - Recommendation: 32, 64, 128 for SDXL - calib_batch_size (int): - The batch size to use for calibration. Defaults to 2. - """ - # Create directories if missing - for directory in [engine_dir, onnx_dir]: - if not os.path.exists(directory): - print(f"[I] Create directory: {directory}") - pathlib.Path(directory).mkdir(parents=True) - - # Initialize models - self.initializeModels(framework_model_dir, int8, fp8) - - # Configure pipeline models to load - model_names = self.models.keys() - lora_suffix = '-'+'-'.join([str(md5(path.encode('utf-8')).hexdigest())+'-'+('%.2f' % self.lora_weights[path])+'-'+('%.2f' % self.lora_loader.scale) for path in sorted(self.lora_loader.paths)]) if self.lora_loader else '' - # Enable refit and LoRA merging only for UNet & UNetXL for now - do_engine_refit = dict(zip(model_names, [not self.pipeline_type.is_sd_xl_refiner() and enable_refit and model_name.startswith('unet') for model_name in model_names])) - do_lora_merge = dict(zip(model_names, [not enable_refit and self.lora_loader and model_name.startswith('unet') for model_name in model_names])) - # Torch fallback for VAE if specified - torch_fallback = dict(zip(model_names, [self.torch_inference for model_name in model_names])) - model_suffix = dict(zip(model_names, [lora_suffix if do_lora_merge[model_name] else '' for model_name in model_names])) - use_int8 = dict.fromkeys(model_names, False) - use_fp8 = dict.fromkeys(model_names, False) - if int8: - assert self.pipeline_type.is_sd_xl_base() or self.version == "1.4", "int8 quantization only supported for SDXL and SD1.4 pipeline" - model_name = 'unetxl' if self.pipeline_type.is_sd_xl() else 'unet' - use_int8[model_name] = True - model_suffix[model_name] += f"-int8.l{quantization_level}.bs2.s{self.denoising_steps}.c{calibration_size}.p{quantization_percentile}.a{quantization_alpha}" - elif fp8: - assert self.pipeline_type.is_sd_xl() or self.version == "1.4", "fp8 quantization only supported for SDXL and SD1.4 pipeline" - model_name = 'unetxl' if self.pipeline_type.is_sd_xl() else 'unet' - use_fp8[model_name] = True - model_suffix[model_name] += f"-fp8.l{quantization_level}.bs2.s{self.denoising_steps}.c{calibration_size}.p{quantization_percentile}.a{quantization_alpha}" - onnx_path = dict(zip(model_names, [self.getOnnxPath(model_name, onnx_dir, opt=False, suffix=model_suffix[model_name]) for model_name in model_names])) - onnx_opt_path = dict(zip(model_names, [self.getOnnxPath(model_name, onnx_dir, suffix=model_suffix[model_name]) for model_name in model_names])) - engine_path = dict(zip(model_names, [self.getEnginePath(model_name, engine_dir, do_engine_refit[model_name], suffix=model_suffix[model_name]) for model_name in model_names])) - weights_map_path = dict(zip(model_names, [(self.getWeightsMapPath(model_name, onnx_dir) if do_engine_refit[model_name] else None) for model_name in model_names])) - - for model_name, obj in self.models.items(): - if torch_fallback[model_name]: - continue - # Export models to ONNX and save weights name mapping - do_export_onnx = not os.path.exists(engine_path[model_name]) and not os.path.exists(onnx_opt_path[model_name]) - do_export_weights_map = weights_map_path[model_name] and not os.path.exists(weights_map_path[model_name]) - if do_export_onnx or do_export_weights_map: - # Non-quantized ONNX export - if not use_int8[model_name] and not use_fp8[model_name]: - obj.export_onnx(onnx_path[model_name], onnx_opt_path[model_name], onnx_opset, opt_image_height, opt_image_width, enable_lora_merge=do_lora_merge[model_name], static_shape=static_shape, lora_loader=self.lora_loader) - else: - pipeline = obj.get_pipeline() - if self.pipeline_type.is_controlnet(): - model = UNet2DConditionControlNetModel(pipeline.unet, pipeline.controlnet.nets) - else: - model = pipeline.unet - if use_fp8[model_name] and quantization_level == 4.0: - set_fmha(model) - - state_dict_path = self.getStateDictPath(model_name, onnx_dir, suffix=model_suffix[model_name]) - if not os.path.exists(state_dict_path): - print(f"[I] Calibrated weights not found, generating {state_dict_path}") - root_dir = os.path.dirname(os.path.abspath(sys.modules["__main__"].__file__)) - calibration_file = os.path.join(root_dir, "calibration_data", "calibration-prompts.txt") - calibration_prompts = load_calib_prompts(calib_batch_size, calibration_file) - if self.pipeline_type.is_controlnet(): - calibration_image_canny = image_module.download_image( - "https://huggingface.co/diffusers/controlnet-canny-sdxl-1.0/resolve/main/out_bird.png" - ) - # "out_bird.png" has 5 images combined in a row. We pick the first image which is the input image. - calibration_image_canny = calibration_image_canny.crop( - (0, 0, calibration_image_canny.width / 5, calibration_image_canny.height) - ) - calibration_images = [calibration_image_canny] - - # TODO check size > calibration_size - def do_calibrate(pipeline, calibration_prompts, **kwargs): - for i_th, prompts in enumerate(calibration_prompts): - if i_th >= kwargs["calib_size"]: - return - pipeline_call_kwargs = { - "prompt": prompts, - "num_inference_steps": kwargs["n_steps"], - "negative_prompt": [ - "normal quality, low quality, worst quality, low res, blurry, nsfw, nude" - ] - * len(prompts), - } - if self.pipeline_type.is_controlnet(): - pipeline_call_kwargs["image"] = calibration_images - pipeline(**pipeline_call_kwargs).images - - def forward_loop(model): - if self.pipeline_type.is_controlnet(): - pipeline.unet = model.unet - pipeline.controlnet.nets = model.controlnets - else: - pipeline.unet = model - do_calibrate( - pipeline=pipeline, - calibration_prompts=calibration_prompts, - calib_size=calibration_size // calib_batch_size, - n_steps=self.denoising_steps, - ) - - print(f"[I] Performing calibration for {calibration_size} steps.") - if use_int8[model_name]: - quant_config = get_int8_config( - model, - quantization_level, - quantization_alpha, - quantization_percentile, - self.denoising_steps - ) - elif use_fp8[model_name]: - quant_config = SD_FP8_FP16_DEFAULT_CONFIG - - # Handle LoRA - if do_lora_merge[model_name]: - assert self.lora_loader is not None - model = merge_loras(model, self.lora_loader) - check_lora(model) - mtq.quantize(model, quant_config, forward_loop) - mto.save(model, state_dict_path) - else: - mto.restore(model, state_dict_path) - - print(f"[I] Generating quantized ONNX model: {onnx_opt_path[model_name]}") - if not os.path.exists(onnx_path[model_name]): - quantize_lvl(self.version, model, quantization_level) - mtq.disable_quantizer(model, filter_func) - if use_fp8[model_name]: - generate_fp8_scales(model) - else: - model = None - obj.export_onnx(onnx_path[model_name], onnx_opt_path[model_name], onnx_opset, opt_image_height, opt_image_width, custom_model=model, static_shape=static_shape) - - # FIXME do_export_weights_map needs ONNX graph - if do_export_weights_map: - print(f"[I] Saving weights map: {weights_map_path[model_name]}") - obj.export_weights_map(onnx_opt_path[model_name], weights_map_path[model_name]) - - # Release temp GPU memory during onnx export to avoid OOM. - gc.collect() - torch.cuda.empty_cache() - - # Build TensorRT engines - for model_name, obj in self.models.items(): - if torch_fallback[model_name]: - continue - engine = engine_module.Engine(engine_path[model_name]) - if not os.path.exists(engine_path[model_name]): - update_output_names = obj.get_output_names() + obj.extra_output_names if obj.extra_output_names else None - # TF32 can be enabled for all precisions (including INT8/FP8) - tf32amp = obj.tf32 - precision_constraints = 'none' - engine.build(onnx_opt_path[model_name], - tf32=tf32amp, - input_profile=obj.get_input_profile( - opt_batch_size, opt_image_height, opt_image_width, - static_batch=static_batch, static_shape=static_shape - ), - enable_refit=do_engine_refit[model_name], - enable_all_tactics=enable_all_tactics, - timing_cache=timing_cache, - update_output_names=update_output_names, - verbose=self.verbose, - builder_optimization_level=optimization_level, - precision_constraints=precision_constraints, - ) - self.engine[model_name] = engine - - # Load TensorRT engines - for model_name, obj in self.models.items(): - if torch_fallback[model_name]: - continue - self.engine[model_name].load() - if do_engine_refit[model_name] and self.lora_loader: - assert weights_map_path[model_name] - with open(weights_map_path[model_name], 'r') as fp_wts: - print(f"[I] Loading weights map: {weights_map_path[model_name]} ") - [weights_name_mapping, weights_shape_mapping] = json.load(fp_wts) - refit_weights_path = self.getRefitNodesPath(model_name, engine_dir, suffix=lora_suffix) - if not os.path.exists(refit_weights_path): - print(f"[I] Saving refit weights: {refit_weights_path}") - model = merge_loras(obj.get_model(), self.lora_loader) - refit_weights, updated_weight_names = engine_module.get_refit_weights( - model.state_dict(), onnx_opt_path[model_name], weights_name_mapping, weights_shape_mapping - ) - torch.save((refit_weights, updated_weight_names), refit_weights_path) - unload_torch_model(model) - else: - print(f"[I] Loading refit weights: {refit_weights_path}") - refit_weights, updated_weight_names = torch.load(refit_weights_path) - self.engine[model_name].refit(refit_weights, updated_weight_names) - - # Load torch models - for model_name, obj in self.models.items(): - if torch_fallback[model_name]: - self.torch_models[model_name] = obj.get_model(torch_inference=self.torch_inference) - - # Release temp GPU memory during onnx export to avoid OOM. - gc.collect() - torch.cuda.empty_cache() - - def calculateMaxDeviceMemory(self): - max_device_memory = 0 - for model_name, engine in self.engine.items(): - max_device_memory = max(max_device_memory, engine.engine.device_memory_size_v2) - return max_device_memory - - def activateEngines(self, shared_device_memory=None): - if shared_device_memory is None: - max_device_memory = self.calculateMaxDeviceMemory() - _, shared_device_memory = cudart.cudaMalloc(max_device_memory) - self.shared_device_memory = shared_device_memory - # Load and activate TensorRT engines - for engine in self.engine.values(): - engine.activate(device_memory=self.shared_device_memory) - - def runEngine(self, model_name, feed_dict): - engine = self.engine[model_name] - return engine.infer(feed_dict, self.stream, use_cuda_graph=self.use_cuda_graph) - - def initialize_latents(self, batch_size, unet_channels, latent_height, latent_width, latents_dtype=torch.float32): - latents_dtype = latents_dtype # text_embeddings.dtype - latents_shape = (batch_size, unet_channels, latent_height, latent_width) - latents = torch.randn(latents_shape, device=self.device, dtype=latents_dtype, generator=self.generator) - # Scale the initial noise by the standard deviation required by the scheduler - latents = latents * self.scheduler.init_noise_sigma - return latents - - def profile_start(self, name, color='blue'): - if self.nvtx_profile: - self.markers[name] = nvtx.start_range(message=name, color=color) - if name in self.events: - cudart.cudaEventRecord(self.events[name][0], 0) - - def profile_stop(self, name): - if name in self.events: - cudart.cudaEventRecord(self.events[name][1], 0) - if self.nvtx_profile: - nvtx.end_range(self.markers[name]) - - def preprocess_images(self, batch_size, images=()): - if not images: - return () - self.profile_start('preprocess', color='pink') - input_images=[] - for image in images: - image = image.to(self.device).float() - if image.shape[0] != batch_size: - image = image.repeat(batch_size, 1, 1, 1) - input_images.append(image) - self.profile_stop('preprocess') - return tuple(input_images) - - def preprocess_controlnet_images(self, batch_size, images=None): - ''' - images: List of PIL.Image.Image - ''' - if images is None: - return None - self.profile_start('preprocess', color='pink') - images = [(np.array(i.convert("RGB")).astype(np.float32) / 255.0)[..., None].transpose(3, 2, 0, 1).repeat(batch_size, axis=0) for i in images] - # do_classifier_free_guidance - images = [torch.cat([torch.from_numpy(i).to(self.device).float()] * 2) for i in images] - images = torch.cat([image[None, ...] for image in images], dim=0) - self.profile_stop('preprocess') - return images - - def encode_prompt(self, prompt, negative_prompt, encoder='clip', pooled_outputs=False, output_hidden_states=False): - self.profile_start(encoder, color='green') - - tokenizer = self.tokenizer2 if encoder == 'clip2' else self.tokenizer - - def tokenize(prompt, output_hidden_states): - text_input_ids = tokenizer( - prompt, - padding="max_length", - max_length=tokenizer.model_max_length, - truncation=True, - return_tensors="pt", - ).input_ids.type(torch.int32).to(self.device) - - text_hidden_states = None - if self.torch_inference: - outputs = self.torch_models[encoder](text_input_ids, output_hidden_states=output_hidden_states) - text_embeddings = outputs[0].clone() - if output_hidden_states: - text_hidden_states = outputs['hidden_states'][-2].clone() - else: - # NOTE: output tensor for CLIP must be cloned because it will be overwritten when called again for negative prompt - outputs = self.runEngine(encoder, {'input_ids': text_input_ids}) - text_embeddings = outputs['text_embeddings'].clone() - if output_hidden_states: - text_hidden_states = outputs['hidden_states'].clone() - return text_embeddings, text_hidden_states - - # Tokenize prompt - text_embeddings, text_hidden_states = tokenize(prompt, output_hidden_states) - - if self.do_classifier_free_guidance: - # Tokenize negative prompt - uncond_embeddings, uncond_hidden_states = tokenize(negative_prompt, output_hidden_states) - - # Concatenate the unconditional and text embeddings into a single batch to avoid doing two forward passes for classifier free guidance - text_embeddings = torch.cat([uncond_embeddings, text_embeddings]).to(dtype=torch.float16) - - if pooled_outputs: - pooled_output = text_embeddings - - if output_hidden_states: - text_embeddings = torch.cat([uncond_hidden_states, text_hidden_states]).to(dtype=torch.float16) if self.do_classifier_free_guidance else text_hidden_states - - self.profile_stop(encoder) - if pooled_outputs: - return text_embeddings, pooled_output - return text_embeddings - - # from diffusers (get_timesteps) - def get_timesteps(self, num_inference_steps, strength, denoising_start=None): - # get the original timestep using init_timestep - if denoising_start is None: - init_timestep = min(int(num_inference_steps * strength), num_inference_steps) - t_start = max(num_inference_steps - init_timestep, 0) - else: - t_start = 0 - - timesteps = self.scheduler.timesteps[t_start * self.scheduler.order :] - - # Strength is irrelevant if we directly request a timestep to start at; - # that is, strength is determined by the denoising_start instead. - if denoising_start is not None: - discrete_timestep_cutoff = int( - round( - self.scheduler.config.num_train_timesteps - - (denoising_start * self.scheduler.config.num_train_timesteps) - ) - ) - - num_inference_steps = (timesteps < discrete_timestep_cutoff).sum().item() - if self.scheduler.order == 2 and num_inference_steps % 2 == 0: - # if the scheduler is a 2nd order scheduler we might have to do +1 - # because `num_inference_steps` might be even given that every timestep - # (except the highest one) is duplicated. If `num_inference_steps` is even it would - # mean that we cut the timesteps in the middle of the denoising step - # (between 1st and 2nd devirative) which leads to incorrect results. By adding 1 - # we ensure that the denoising process always ends after the 2nd derivate step of the scheduler - num_inference_steps = num_inference_steps + 1 - - # because t_n+1 >= t_n, we slice the timesteps starting from the end - timesteps = timesteps[-num_inference_steps:] - return timesteps, num_inference_steps - - return timesteps, num_inference_steps - t_start - - def denoise_latent(self, - latents, - text_embeddings, - denoiser='unet', - timesteps=None, - step_offset=0, - mask=None, - masked_image_latents=None, - image_guidance=1.5, - controlnet_imgs=None, - controlnet_scales=None, - text_embeds=None, - time_ids=None): - - assert image_guidance > 1.0, "Image guidance has to be > 1.0" - - controlnet_imgs = self.preprocess_controlnet_images(latents.shape[0], controlnet_imgs) - - do_autocast = self.torch_inference != '' and self.models[denoiser].fp16 - with torch.autocast('cuda', enabled=do_autocast): - self.profile_start(denoiser, color='blue') - for step_index, timestep in enumerate(timesteps): - # Expand the latents if we are doing classifier free guidance - latent_model_input = torch.cat([latents] * 2) if self.do_classifier_free_guidance else latents - latent_model_input = self.scheduler.scale_model_input(latent_model_input, timestep) - if isinstance(mask, torch.Tensor): - latent_model_input = torch.cat([latent_model_input, mask, masked_image_latents], dim=1) - - # Predict the noise residual - if self.torch_inference: - params = {"sample": latent_model_input, "timestep": timestep, "encoder_hidden_states": text_embeddings} - if controlnet_imgs is not None: - params.update({"images": controlnet_imgs, "controlnet_scales": controlnet_scales}) - added_cond_kwargs = {} - if text_embeds != None: - added_cond_kwargs.update({'text_embeds': text_embeds}) - if time_ids != None: - added_cond_kwargs.update({'time_ids': time_ids}) - if text_embeds != None or time_ids != None: - params.update({'added_cond_kwargs': added_cond_kwargs}) - noise_pred = self.torch_models[denoiser](**params)["sample"] - else: - timestep_float = timestep.float() if timestep.dtype != torch.float32 else timestep - - params = {"sample": latent_model_input, "timestep": timestep_float, "encoder_hidden_states": text_embeddings} - if controlnet_imgs is not None: - params.update({"images": controlnet_imgs, "controlnet_scales": controlnet_scales}) - if text_embeds != None: - params.update({'text_embeds': text_embeds}) - if time_ids != None: - params.update({'time_ids': time_ids}) - noise_pred = self.runEngine(denoiser, params)['latent'] - - # Perform guidance - if self.do_classifier_free_guidance: - noise_pred_uncond, noise_pred_text = noise_pred.chunk(2) - noise_pred = noise_pred_uncond + self.guidance_scale * (noise_pred_text - noise_pred_uncond) - - # from diffusers (prepare_extra_step_kwargs) - extra_step_kwargs = {} - if "eta" in set(inspect.signature(self.scheduler.step).parameters.keys()): - # TODO: configurable eta - eta = 0.0 - extra_step_kwargs["eta"] = eta - if "generator" in set(inspect.signature(self.scheduler.step).parameters.keys()): - extra_step_kwargs["generator"] = self.generator - - latents = self.scheduler.step(noise_pred, timestep, latents, **extra_step_kwargs, return_dict=False)[0] - - latents = 1. / self.vae_scaling_factor * latents - latents = latents.to(dtype=torch.float32) - - self.profile_stop(denoiser) - return latents - - def encode_image(self, input_image): - self.profile_start('vae_encoder', color='red') - cast_to = torch.float16 if self.models['vae_encoder'].fp16 else torch.bfloat16 if self.models['vae_encoder'].bf16 else torch.float32 - input_image = input_image.to(dtype=cast_to) - if self.torch_inference: - image_latents = self.torch_models['vae_encoder'](input_image) - else: - image_latents = self.runEngine('vae_encoder', {'images': input_image})['latent'] - image_latents = self.vae_scaling_factor * image_latents - self.profile_stop('vae_encoder') - return image_latents - - def decode_latent(self, latents): - self.profile_start('vae', color='red') - cast_to = torch.float16 if self.models['vae'].fp16 else torch.bfloat16 if self.models['vae'].bf16 else torch.float32 - latents = latents.to(dtype=cast_to) - - if self.torch_inference: - images = self.torch_models['vae'](latents, return_dict=False)[0] - else: - images = self.runEngine('vae', {'latent': latents})['images'] - self.profile_stop('vae') - return images - - def print_summary(self, denoising_steps, walltime_ms, batch_size): - print('|-----------------|--------------|') - print('| {:^15} | {:^12} |'.format('Module', 'Latency')) - print('|-----------------|--------------|') - for stage in self.stages: - stage_name = stage - if "unet" in stage: - if self.pipeline_type.is_controlnet(): - stage_name += '+cnet' - stage_name += ' x ' + str(denoising_steps) - print( - "| {:^15} | {:>9.2f} ms |".format( - stage_name, cudart.cudaEventElapsedTime(self.events[stage][0], self.events[stage][1])[1], - ) - ) - print('|-----------------|--------------|') - print('| {:^15} | {:>9.2f} ms |'.format('Pipeline', walltime_ms)) - print('|-----------------|--------------|') - print('Throughput: {:.5f} image/s'.format(batch_size*1000./walltime_ms)) - - def save_image(self, images, pipeline, prompt, seed): - # Save image - image_name_prefix = pipeline+''.join(set(['-'+prompt[i].replace(' ','_')[:10] for i in range(len(prompt))]))+'-'+str(seed)+'-' - image_name_suffix = 'torch' if self.torch_inference else 'trt' - image_module.save_image(images, self.output_dir, image_name_prefix, image_name_suffix) - - def infer( - self, - prompt, - negative_prompt, - image_height, - image_width, - input_image=None, - image_strength=0.75, - controlnet_scales=None, - aesthetic_score=6.0, - negative_aesthetic_score=2.5, - warmup=False, - verbose=False, - save_image=True, - ): - """ - Run the diffusion pipeline. - - Args: - prompt (str): - The text prompt to guide image generation. - negative_prompt (str): - The prompt not to guide the image generation. - image_height (int): - Height (in pixels) of the image to be generated. Must be a multiple of 8. - image_width (int): - Width (in pixels) of the image to be generated. Must be a multiple of 8. - input_image (image): - Input image used to initialize the latents. - image_strength (float): - Strength of transformation applied to input_image. Must be between 0 and 1. - controlnet_scales (torch.Tensor) - A tensor which containes ControlNet scales, essential for multi ControlNet. - Must be equal to number of Controlnets. - warmup (bool): - Indicate if this is a warmup run. - verbose (bool): - Verbose in logging - save_image (bool): - Save the generated image (if applicable) - """ - assert len(prompt) == len(negative_prompt) - batch_size = len(prompt) - - # Spatial dimensions of latent tensor - latent_height = image_height // 8 - latent_width = image_width // 8 - - if self.generator and self.seed: - self.generator.manual_seed(self.seed) - - num_inference_steps = self.denoising_steps - - with torch.inference_mode(), trt.Runtime(TRT_LOGGER): - torch.cuda.synchronize() - e2e_tic = time.perf_counter() - - # TODO: support custom timesteps - timesteps = None - if timesteps is not None: - if "timesteps" not in set(inspect.signature(self.scheduler.set_timesteps).parameters.keys()): - raise ValueError( - f"The current scheduler class {self.scheduler.__class__}'s `set_timesteps` does not support custom" - f" timestep schedules. Please check whether you are using the correct scheduler." - ) - self.scheduler.set_timesteps(timesteps=timesteps, device=self.device) - assert self.denoising_steps == len(self.scheduler.timesteps) - else: - self.scheduler.set_timesteps(self.denoising_steps, device=self.device) - timesteps = self.scheduler.timesteps.to(self.device) - - denoise_kwargs = {} - if not (self.pipeline_type.is_img2img() or self.pipeline_type.is_sd_xl_refiner()): - # Initialize latents - latents = self.initialize_latents(batch_size=batch_size, - unet_channels=4, - latent_height=latent_height, - latent_width=latent_width) - if self.pipeline_type.is_controlnet(): - denoise_kwargs.update({'controlnet_imgs': input_image, 'controlnet_scales': controlnet_scales}) - - # Pre-process and VAE encode input image - if self.pipeline_type.is_img2img() or self.pipeline_type.is_sd_xl_refiner(): - assert input_image != None - # Initialize timesteps and pre-process input image - timesteps, num_inference_steps = self.get_timesteps(self.denoising_steps, image_strength) - denoise_kwargs.update({'timesteps': timesteps}) - if self.pipeline_type.is_img2img() or self.pipeline_type.is_sd_xl_refiner(): - latent_timestep = timesteps[:1].repeat(batch_size) - input_image = self.preprocess_images(batch_size, (input_image,))[0] - # Encode if not a latent - image_latents = input_image if input_image.shape[1] == 4 else self.encode_image(input_image) - # Add noise to latents using timesteps - noise = torch.randn(image_latents.shape, generator=self.generator, device=self.device, dtype=torch.float32) - latents = self.scheduler.add_noise(image_latents, noise, latent_timestep) - - # CLIP text encoder(s) - if self.pipeline_type.is_sd_xl(): - text_embeddings2, pooled_embeddings2 = self.encode_prompt(prompt, negative_prompt, - encoder='clip2', pooled_outputs=True, output_hidden_states=True) - - # Merge text embeddings - if self.pipeline_type.is_sd_xl_base(): - text_embeddings = self.encode_prompt(prompt, negative_prompt, output_hidden_states=True) - text_embeddings = torch.cat([text_embeddings, text_embeddings2], dim=-1) - else: - text_embeddings = text_embeddings2 - - # Time embeddings - def _get_add_time_ids(original_size, crops_coords_top_left, target_size, dtype, aesthetic_score=None, negative_aesthetic_score=None): - if self.pipeline_type.is_sd_xl_refiner(): #self.requires_aesthetics_score: - add_time_ids = list(original_size + crops_coords_top_left + (aesthetic_score,)) - if self.do_classifier_free_guidance: - add_neg_time_ids = list(original_size + crops_coords_top_left + (negative_aesthetic_score,)) - else: - add_time_ids = list(original_size + crops_coords_top_left + target_size) - if self.do_classifier_free_guidance: - add_neg_time_ids = list(original_size + crops_coords_top_left + target_size) - add_time_ids = torch.tensor([add_time_ids], dtype=dtype, device=self.device) - if self.do_classifier_free_guidance: - add_neg_time_ids = torch.tensor([add_neg_time_ids], dtype=dtype, device=self.device) - add_time_ids = torch.cat([add_neg_time_ids, add_time_ids], dim=0) - return add_time_ids - - original_size = (image_height, image_width) - crops_coords_top_left = (0, 0) - target_size = (image_height, image_width) - if self.pipeline_type.is_sd_xl_refiner(): - add_time_ids = _get_add_time_ids( - original_size, crops_coords_top_left, target_size, dtype=text_embeddings.dtype, aesthetic_score=aesthetic_score, negative_aesthetic_score=negative_aesthetic_score - ) - else: - add_time_ids = _get_add_time_ids( - original_size, crops_coords_top_left, target_size, dtype=text_embeddings.dtype - ) - add_time_ids = add_time_ids.repeat(batch_size, 1) - denoise_kwargs.update({'text_embeds': pooled_embeddings2, 'time_ids': add_time_ids}) - else: - text_embeddings = self.encode_prompt(prompt, negative_prompt) - - # UNet denoiser + (optional) ControlNet(s) - denoiser = 'unetxl' if self.pipeline_type.is_sd_xl() else 'unet' - latents = self.denoise_latent(latents, text_embeddings, denoiser=denoiser, **denoise_kwargs) - - # VAE decode latent (if applicable) - if self.return_latents: - latents = latents * self.vae_scaling_factor - else: - images = self.decode_latent(latents) - - torch.cuda.synchronize() - e2e_toc = time.perf_counter() - - walltime_ms = (e2e_toc - e2e_tic) * 1000. - if not warmup: - self.print_summary(num_inference_steps, walltime_ms, batch_size) - if not self.return_latents and save_image: - # post-process images - images = ((images + 1) * 255 / 2).clamp(0, 255).detach().permute(0, 2, 3, 1).round().type(torch.uint8).cpu().numpy() - self.save_image(images, self.pipeline_type.name.lower(), prompt, self.seed) - - return (latents, walltime_ms) if self.return_latents else (images, walltime_ms) - - def run(self, prompt, negative_prompt, height, width, batch_size, batch_count, num_warmup_runs, use_cuda_graph, **kwargs): - # Process prompt - if not isinstance(prompt, list): - raise ValueError(f"`prompt` must be of type `str` list, but is {type(prompt)}") - prompt = prompt * batch_size - - if not isinstance(negative_prompt, list): - raise ValueError(f"`--negative-prompt` must be of type `str` list, but is {type(negative_prompt)}") - if len(negative_prompt) == 1: - negative_prompt = negative_prompt * batch_size - - num_warmup_runs = max(1, num_warmup_runs) if use_cuda_graph else num_warmup_runs - if num_warmup_runs > 0: - print("[I] Warming up ..") - for _ in range(num_warmup_runs): - self.infer(prompt, negative_prompt, height, width, warmup=True, **kwargs) - - for _ in range(batch_count): - print("[I] Running StableDiffusion pipeline") - if self.nvtx_profile: - cudart.cudaProfilerStart() - self.infer(prompt, negative_prompt, height, width, warmup=False, **kwargs) - if self.nvtx_profile: - cudart.cudaProfilerStop() diff --git a/demo/Diffusion/demo_diffusion/pipeline/stable_video_diffusion_pipeline.py b/demo/Diffusion/demo_diffusion/pipeline/stable_video_diffusion_pipeline.py deleted file mode 100644 index 73ae2a7e5..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/stable_video_diffusion_pipeline.py +++ /dev/null @@ -1,751 +0,0 @@ -# -# Copyright 2024 The HuggingFace Inc. team. -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -import os -import pathlib -import random -import sys -import time -from typing import Optional - -import modelopt.torch.opt as mto -import modelopt.torch.quantization as mtq -import tensorrt as trt -import torch -from cuda.bindings import runtime as cudart -from diffusers.image_processor import VaeImageProcessor -from diffusers.utils.torch_utils import randn_tensor -from tqdm.auto import tqdm - -import demo_diffusion.engine as engine_module -import demo_diffusion.image as image_module -from demo_diffusion.model import ( - CLIPImageProcessorModel, - CLIPVisionWithProjModel, - UNetTemporalModel, - VAEDecTemporalModel, -) -from demo_diffusion.pipeline.calibrate import load_calibration_images -from demo_diffusion.pipeline.stable_diffusion_pipeline import StableDiffusionPipeline -from demo_diffusion.pipeline.type import PIPELINE_TYPE -from demo_diffusion.utils_modelopt import ( - SD_FP8_FP16_DEFAULT_CONFIG, - check_lora, - filter_func, - generate_fp8_scales, - quantize_lvl, -) - -TRT_LOGGER = trt.Logger(trt.Logger.ERROR) - - -def _GiB(val): - return val * 1 << 30 - - -def _append_dims(x, target_dims): - """Appends dimensions to the end of a tensor until it has target_dims dimensions.""" - dims_to_append = target_dims - x.ndim - if dims_to_append < 0: - raise ValueError(f"input has {x.ndim} dims but target_dims is {target_dims}, which is less") - return x[(...,) + (None,) * dims_to_append] - - -class StableVideoDiffusionPipeline(StableDiffusionPipeline): - """ - Application showcasing the acceleration of Stable Video Diffusion pipelines using NVidia TensorRT. - """ - def __init__( - self, - version='svd-xt-1.1', - pipeline_type=PIPELINE_TYPE.IMG2VID, - min_guidance_scale: float = 1.0, - max_guidance_scale: float = 3.0, - decode_chunk_size: Optional[int] = None, - **kwargs - ): - """ - Initializes the Diffusion pipeline. - - Args: - version (str): - The version of the pipeline. Should be one of [svd-xt-1.1] - pipeline_type (PIPELINE_TYPE): - Type of current pipeline. - min_guidance_scale (`float`, *optional*, defaults to 1.0): - The minimum guidance scale. Used for the classifier free guidance with first frame. - max_guidance_scale (`float`, *optional*, defaults to 3.0): - The maximum guidance scale. Used for the classifier free guidance with last frame. - `max_guidance_scale = 1` corresponds to doing no classifier free guidance. - decode_chunk_size (`int`, *optional*): - The number of frames to decode at a time. The higher the chunk size, the higher the temporal consistency - between frames, but also the higher the memory consumption. By default, the decoder will decode all frames at once - for maximal quality. Reduce `decode_chunk_size` to reduce memory usage. - """ - super().__init__( - version=version, - pipeline_type=pipeline_type, - **kwargs - ) - self.min_guidance_scale = min_guidance_scale - self.max_guidance_scale = max_guidance_scale - self.do_classifier_free_guidance = max_guidance_scale > 1 - # FIXME vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1) - self.vae_scale_factor = 8 - # FIXME num_frames = self.config.num_frames - select_num_frames = { - 'svd-xt-1.1': 25, - } - self.num_frames = select_num_frames.get(version, 14) - # TODO decode_chunk_size from args - self.decode_chunk_size = 8 if not decode_chunk_size else decode_chunk_size - # TODO: scaling_factor = vae.config.scaling_factor - self.scaling_factor = 0.18215 - - # TODO user configurable cuda_device_id - cuda_device_id = 0 - properties = cudart.cudaGetDeviceProperties(cuda_device_id) - if properties[0] != 0: - total_device_count = cudart.cudaGetDeviceCount()[1] - raise ValueError(f"Failed to get device properties for device {cuda_device_id}, total device count: {total_device_count}") - vram_size = properties[1].totalGlobalMem - self.low_vram = vram_size < _GiB(40) - if self.low_vram: - print(f"[W] WARNING low VRAM ({vram_size/_GiB(1):.2f} GB) mode selected. Certain optimizations may be skipped.") - if self.use_cuda_graph and self.low_vram: - print("[W] WARNING CUDA graph disabled in low VRAM mode.") - self.use_cuda_graph = False - - self.config = {} - if self.pipeline_type.is_img2vid(): - self.config['clip_vis_torch_fallback'] = True - self.config['clip_imgfe_torch_fallback'] = True - self.config['vae_temp_torch_fallback'] = True - - # initialized in loadEngines() - self.max_shared_device_memory_size = 0 - - def loadResources(self, image_height, image_width, batch_size, seed): - # Initialize noise generator - self.seed = seed - self.generator = torch.Generator(device="cuda").manual_seed(seed) if seed else None - - # Create CUDA events and stream - for stage in ['clip', 'denoise', 'vae', 'vae_encoder']: - self.events[stage] = [cudart.cudaEventCreate()[1], cudart.cudaEventCreate()[1]] - self.stream = cudart.cudaStreamCreate()[1] - - # Allocate shared device memory for TensorRT engines - if not self.low_vram and not self.torch_inference: - for model_name in self.models.keys(): - if not self.torch_fallback[model_name]: - self.max_shared_device_memory_size = max(self.max_shared_device_memory_size, self.engine[model_name].engine.device_memory_size_v2) - self.shared_device_memory = cudart.cudaMalloc(self.max_shared_device_memory_size)[1] - # Activate TensorRT engines - for model_name in self.models.keys(): - if not self.torch_fallback[model_name]: - self.engine[model_name].activate(device_memory=self.shared_device_memory) - alloc_shape = self.models[model_name].get_shape_dict(batch_size, image_height, image_width) - self.engine[model_name].allocate_buffers(shape_dict=alloc_shape, device=self.device) - - def loadEngines( - self, - engine_dir, - framework_model_dir, - onnx_dir, - onnx_opset, - opt_batch_size, - opt_image_height, - opt_image_width, - static_batch=False, - static_shape=True, - enable_refit=False, - enable_all_tactics=False, - timing_cache=None, - fp8=False, - quantization_level=0.0, - calibration_size=32, - calib_batch_size=2, - **_kwargs, - ): - """ - Build and load engines for TensorRT accelerated inference. - Export ONNX models first, if applicable. - - Args: - engine_dir (str): - Directory to store the TensorRT engines. - framework_model_dir (str): - Directory to store the framework model ckpt. - onnx_dir (str): - Directory to store the ONNX models. - onnx_opset (int): - ONNX opset version to export the models. - opt_batch_size (int): - Batch size to optimize for during engine building. - opt_image_height (int): - Image height to optimize for during engine building. Must be a multiple of 8. - opt_image_width (int): - Image width to optimize for during engine building. Must be a multiple of 8. - static_batch (bool): - Build engine only for specified opt_batch_size. - static_shape (bool): - Build engine only for specified opt_image_height & opt_image_width. Default = True. - enable_refit (bool): - Build engines with refit option enabled. - enable_all_tactics (bool): - Enable all tactic sources during TensorRT engine builds. - timing_cache (str): - Path to the timing cache to speed up TensorRT build. - fp8 (bool): - Whether to quantize to fp8 format or not. - quantization_level (float): - Controls which layers to quantize. - calibration_size (int): - The number of steps to use for calibrating the model for quantization. - calib_batch_size (int): - The batch size to use for calibration. Defaults to 2. - """ - # Create directories if missing - for directory in [engine_dir, onnx_dir]: - if not os.path.exists(directory): - print(f"[I] Create directory: {directory}") - pathlib.Path(directory).mkdir(parents=True) - - # Load pipeline models - models_args = {'version': self.version, 'pipeline': self.pipeline_type, 'device': self.device, - 'hf_token': self.hf_token, 'verbose': self.verbose, 'framework_model_dir': framework_model_dir, - 'max_batch_size': self.max_batch_size} - if 'clip-vis' in self.stages: - self.models['clip-vis'] = CLIPVisionWithProjModel(**models_args, subfolder='image_encoder') - if 'clip-imgfe' in self.stages: - self.models['clip-imgfe'] = CLIPImageProcessorModel(**models_args, subfolder='feature_extractor') - if 'unet-temp' in self.stages: - self.models['unet-temp'] = UNetTemporalModel(**models_args, fp16=True, fp8=fp8, num_frames=self.num_frames, do_classifier_free_guidance=self.do_classifier_free_guidance) - if 'vae-temp' in self.stages: - self.models['vae-temp'] = VAEDecTemporalModel(**models_args, decode_chunk_size=self.decode_chunk_size) - self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor) - - # Configure pipeline models to load - model_names = self.models.keys() - self.torch_fallback = dict(zip(model_names, [self.torch_inference or self.config.get(model_name.replace('-','_')+'_torch_fallback', False) for model_name in model_names])) - onnx_path = dict(zip(model_names, [self.getOnnxPath(model_name, onnx_dir, opt=False) for model_name in model_names])) - onnx_opt_path = dict(zip(model_names, [self.getOnnxPath(model_name, onnx_dir) for model_name in model_names])) - engine_path = dict(zip(model_names, [self.getEnginePath(model_name, engine_dir) for model_name in model_names])) - do_engine_refit = dict(zip(model_names, [enable_refit and model_name.startswith('unet') for model_name in model_names])) - - # Quantization. - model_suffix = dict(zip(model_names, ['' for model_name in model_names])) - use_fp8 = dict.fromkeys(model_names, False) - if fp8: - model_name = "unet-temp" - use_fp8[model_name] = True - model_suffix[model_name] += f"-fp8.l{quantization_level}.bs2.s{self.denoising_steps}.c{calibration_size}" - onnx_path = { model_name : self.getOnnxPath(model_name, onnx_dir, opt=False, suffix=model_suffix[model_name]) for model_name in model_names } - onnx_opt_path = { model_name : self.getOnnxPath(model_name, onnx_dir, suffix=model_suffix[model_name]) for model_name in model_names } - engine_path = { model_name : self.getEnginePath(model_name, engine_dir, do_engine_refit[model_name], suffix=model_suffix[model_name]) for model_name in model_names } - weights_map_path = { model_name : (self.getWeightsMapPath(model_name, onnx_dir) if do_engine_refit[model_name] else None) for model_name in model_names } - - # Export models to ONNX - for model_name, obj in self.models.items(): - if self.torch_fallback[model_name]: - continue - do_export_onnx = not os.path.exists(engine_path[model_name]) and not os.path.exists(onnx_opt_path[model_name]) - do_export_weights_map = weights_map_path[model_name] and not os.path.exists(weights_map_path[model_name]) - if do_export_onnx or do_export_weights_map: - if use_fp8[model_name]: - pipeline = obj.get_pipeline() - model = pipeline.unet - - state_dict_path = self.getStateDictPath(model_name, onnx_dir, suffix=model_suffix[model_name]) - if not os.path.exists(state_dict_path): - # Load calibration images - print(f"[I] Calibrated weights not found, generating {state_dict_path}") - root_dir = os.path.dirname(os.path.abspath(sys.modules["__main__"].__file__)) - calibration_image_folder = os.path.join(root_dir, "calibration_data", "calibration-images") - calibration_image_list = load_calibration_images(calibration_image_folder) - print("Number of images loaded:", len(calibration_image_list)) - - # TODO check size > calibration_size - def do_calibrate(pipeline, calibration_images, **kwargs): - for i_th, image in enumerate(calibration_images): - if i_th >= kwargs["calib_size"]: - return - pipeline( - image=image, - num_inference_steps=kwargs["n_steps"], - ).frames[0] - - def forward_loop(model): - pipeline.unet = model - do_calibrate( - pipeline=pipeline, - calibration_images=calibration_image_list, - calib_size=calibration_size // calib_batch_size, - n_steps=self.denoising_steps, - ) - - print(f"[I] Performing calibration for {calibration_size} steps.") - if use_fp8[model_name]: - quant_config = SD_FP8_FP16_DEFAULT_CONFIG - check_lora(model) - mtq.quantize(model, quant_config, forward_loop) - mto.save(model, state_dict_path) - else: - mto.restore(model, state_dict_path) - - print(f"[I] Generating quantized ONNX model: {onnx_opt_path[model_name]}") - if not os.path.exists(onnx_path[model_name]): - """ - Error: Torch bug, ONNX export failed due to unknown kernel shape in QuantConv3d. - TRT_FP8QuantizeLinear and TRT_FP8DequantizeLinear operations in UNetSpatioTemporalConditionModel for svd - cause issues. Inputs on different devices (CUDA vs CPU) may contribute to the problem. - """ - quantize_lvl(self.version, model, quantization_level, enable_conv_3d=False) - mtq.disable_quantizer(model, filter_func) - if use_fp8[model_name]: - generate_fp8_scales(model) - else: - model = None - - obj.export_onnx(onnx_path[model_name], onnx_opt_path[model_name], onnx_opset, opt_image_height, opt_image_width, custom_model=model, static_shape=static_shape) - else: - obj.export_onnx(onnx_path[model_name], onnx_opt_path[model_name], onnx_opset, opt_image_height, opt_image_width) - - # Clean model cache - torch.cuda.empty_cache() - - # Build TensorRT engines - for model_name, obj in self.models.items(): - if self.torch_fallback[model_name]: - continue - engine = engine_module.Engine(engine_path[model_name]) - if not os.path.exists(engine_path[model_name]): - update_output_names = obj.get_output_names() + obj.extra_output_names if obj.extra_output_names else None - engine.build(onnx_opt_path[model_name], - input_profile=obj.get_input_profile( - opt_batch_size, opt_image_height, opt_image_width, - static_batch=static_batch, static_shape=static_shape - ), - enable_refit=do_engine_refit[model_name], - enable_all_tactics=enable_all_tactics, - timing_cache=timing_cache, - update_output_names=update_output_names, - native_instancenorm=False) - self.engine[model_name] = engine - - # Load TensorRT engines - for model_name in self.models.keys(): - if not self.torch_fallback[model_name]: - self.engine[model_name].load() - - def activateEngines(self, model_name, alloc_shape=None): - if not self.torch_fallback[model_name]: - device_memory_update = self.low_vram and not self.shared_device_memory - if device_memory_update: - assert not self.use_cuda_graph - # Reclaim GPU memory from torch cache - torch.cuda.empty_cache() - self.shared_device_memory = cudart.cudaMalloc(self.max_shared_device_memory_size)[1] - # Create TensorRT execution context - if not self.engine[model_name].context: - assert not self.use_cuda_graph - self.engine[model_name].activate(device_memory=self.shared_device_memory) - if device_memory_update: - self.engine[model_name].reactivate(device_memory=self.shared_device_memory) - if alloc_shape and not self.engine[model_name].tensors: - assert not self.use_cuda_graph - self.engine[model_name].allocate_buffers(shape_dict=alloc_shape, device=self.device) - else: - # Load torch model - if model_name not in self.torch_models: - self.torch_models[model_name] = self.models[model_name].get_model(torch_inference=self.torch_inference) - - def deactivateEngines(self, model_name, release_model=True): - if not release_model: - return - if not self.torch_fallback[model_name]: - assert not self.use_cuda_graph - self.engine[model_name].deallocate_buffers() - self.engine[model_name].deactivate() - # Shared device memory deallocated only in low VRAM mode - if self.low_vram and self.shared_device_memory: - cudart.cudaFree(self.shared_device_memory) - self.shared_device_memory = None - else: - del self.torch_models[model_name] - - def print_summary(self, denoising_steps, walltime_ms, batch_size, num_frames): - print('|-----------------|--------------|') - print('| {:^15} | {:^12} |'.format('Module', 'Latency')) - print('|-----------------|--------------|') - print('| {:^15} | {:>9.2f} ms |'.format('VAE-Enc', cudart.cudaEventElapsedTime(self.events['vae_encoder'][0], self.events['vae_encoder'][1])[1])) - print('| {:^15} | {:>9.2f} ms |'.format('CLIP', cudart.cudaEventElapsedTime(self.events['clip'][0], self.events['clip'][1])[1])) - print('| {:^15} | {:>9.2f} ms |'.format('UNet'+('+CNet' if self.pipeline_type.is_controlnet() else '')+' x '+str(denoising_steps), cudart.cudaEventElapsedTime(self.events['denoise'][0], self.events['denoise'][1])[1])) - print('| {:^15} | {:>9.2f} ms |'.format('VAE-Dec', cudart.cudaEventElapsedTime(self.events['vae'][0], self.events['vae'][1])[1])) - print('|-----------------|--------------|') - print('| {:^15} | {:>9.2f} ms |'.format('Pipeline', walltime_ms)) - print('|-----------------|--------------|') - print('Throughput: {:.5f} videos/min ({} frames)'.format(batch_size*60000./walltime_ms, num_frames)) - - def save_video(self, frames, pipeline, seed): - video_name_prefix = '-'.join([pipeline, 'fp16', str(seed), str(random.randint(1000,9999))]) - video_name_suffix = 'torch' if self.torch_inference else 'trt' - video_path = video_name_prefix+'-'+video_name_suffix+'.gif' - print(f"Saving video to: {video_path}") - frames[0].save(os.path.join(self.output_dir, video_path), save_all=True,optimize=False, append_images=frames[1:], loop=0) - - def _encode_image(self, image, num_videos_per_prompt, do_classifier_free_guidance): - dtype = next(self.torch_models['clip-vis'].parameters()).dtype - - if not isinstance(image, torch.Tensor): - image = self.image_processor.pil_to_numpy(image) - image = self.image_processor.numpy_to_pt(image) - - # We normalize the image before resizing to match with the original implementation. - # Then we unnormalize it after resizing. - image = image * 2.0 - 1.0 - image = image_module.resize_with_antialiasing(image, (224, 224)) - image = (image + 1.0) / 2.0 - - # Normalize the image with for CLIP input - image = self.torch_models['clip-imgfe']( - images=image, - do_normalize=True, - do_center_crop=False, - do_resize=False, - do_rescale=False, - return_tensors="pt", - ).pixel_values - - image = image.to(device=self.device, dtype=dtype) - image_embeddings = self.torch_models['clip-vis'](image).image_embeds - image_embeddings = image_embeddings.unsqueeze(1) - - # duplicate image embeddings for each generation per prompt, using mps friendly method - bs_embed, seq_len, _ = image_embeddings.shape - image_embeddings = image_embeddings.repeat(1, num_videos_per_prompt, 1) - image_embeddings = image_embeddings.view(bs_embed * num_videos_per_prompt, seq_len, -1) - - if do_classifier_free_guidance: - negative_image_embeddings = torch.zeros_like(image_embeddings) - - # For classifier free guidance, we need to do two forward passes. - # Here we concatenate the unconditional and text embeddings into a single batch - # to avoid doing two forward passes - image_embeddings = torch.cat([negative_image_embeddings, image_embeddings]) - - return image_embeddings - - def _encode_vae_image( - self, - image: torch.Tensor, - device, - num_videos_per_prompt, - do_classifier_free_guidance, - ): - image = image.to(device=device) - image_latents = self.torch_models['vae-temp'].encode(image).latent_dist.mode() - - if do_classifier_free_guidance: - negative_image_latents = torch.zeros_like(image_latents) - - # For classifier free guidance, we need to do two forward passes. - # Here we concatenate the unconditional and text embeddings into a single batch - # to avoid doing two forward passes - image_latents = torch.cat([negative_image_latents, image_latents]) - - # duplicate image_latents for each generation per prompt, using mps friendly method - image_latents = image_latents.repeat(num_videos_per_prompt, 1, 1, 1) - - return image_latents - - def _get_add_time_ids( - self, - fps, - motion_bucket_id, - noise_aug_strength, - dtype, - batch_size, - num_videos_per_prompt, - do_classifier_free_guidance, - ): - add_time_ids = [fps, motion_bucket_id, noise_aug_strength] - add_time_ids = torch.tensor([add_time_ids], dtype=dtype) - add_time_ids = add_time_ids.repeat(batch_size * num_videos_per_prompt, 1) - - if do_classifier_free_guidance: - add_time_ids = torch.cat([add_time_ids, add_time_ids]) - - return add_time_ids - - def prepare_latents( - self, - batch_size, - num_frames, - num_channels_latents, - height, - width, - dtype, - device, - latents=None, - ): - shape = ( - batch_size, - num_frames, - num_channels_latents // 2, - height // self.vae_scale_factor, - width // self.vae_scale_factor, - ) - - if latents is None: - latents = randn_tensor(shape, generator=self.generator, device=device, dtype=dtype) - else: - latents = latents.to(device) - - # scale the initial noise by the standard deviation required by the scheduler - latents = latents * self.scheduler.init_noise_sigma - return latents - - def decode_latents(self, latents, num_frames, decode_chunk_size): - # [batch, frames, channels, height, width] -> [batch*frames, channels, height, width] - latents = latents.flatten(0, 1) - - latents = 1 / self.scaling_factor * latents - - # decode decode_chunk_size frames at a time to avoid OOM - frames = [] - for i in range(0, latents.shape[0], decode_chunk_size): - num_frames_in = latents[i : i + decode_chunk_size].shape[0] - # TODO only pass num_frames_in if it's expected - if self.torch_fallback['vae-temp']: - frame = self.torch_models['vae-temp'].decode(latents[i : i + decode_chunk_size], num_frames=num_frames_in).sample - else: - params = { - 'latent': latents[i : i + decode_chunk_size], - # FIXME segfault - #'num_frames_in': torch.Tensor([num_frames_in]).to(device=latents.device, dtype=torch.int64), - } - frame = self.runEngine('vae-temp', params)['frames'] - frames.append(frame) - frames = torch.cat(frames, dim=0) - - # [batch*frames, channels, height, width] -> [batch, channels, frames, height, width] - frames = frames.reshape(-1, num_frames, *frames.shape[1:]).permute(0, 2, 1, 3, 4) - - # we always cast to float32 as this does not cause significant overhead and is compatible with bfloat16 - frames = frames.float() - return frames - - def infer( - self, - input_image, - image_height: int, - image_width: int, - fps: int = 7, - motion_bucket_id: int = 127, - noise_aug_strength: int = 0.02, - num_videos_per_prompt: Optional[int] = 1, - warmup: bool = False, - save_video: bool = True, - ): - """ - Run the video diffusion pipeline. - - Args: - input_image (image): - Input image used to initialize the latents. - image_height (int): - Height (in pixels) of the image to be generated. Must be a multiple of 8. - image_width (int): - Width (in pixels) of the image to be generated. Must be a multiple of 8. - fps (`int`, *optional*, defaults to 7): - Frames per second. The rate at which the generated images shall be exported to a video after generation. - Note that Stable Diffusion Video's UNet was micro-conditioned on fps-1 during training. - motion_bucket_id (`int`, *optional*, defaults to 127): - The motion bucket ID. Used as conditioning for the generation. The higher the number the more motion will be in the video. - noise_aug_strength (`int`, *optional*, defaults to 0.02): - The amount of noise added to the init image, the higher it is the less the video will look like the init image. Increase it for more motion. - num_videos_per_prompt (`int`, *optional*, defaults to 1): - The number of images to generate per prompt. - warmup (bool): - Indicate if this is a warmup run. - save_video (bool): - Save the video image. - """ - - if self.generator and self.seed: - self.generator.manual_seed(self.seed) - - # TODO - batch_size = 1 - # Fast warmup - denoising_steps = 1 if warmup else self.denoising_steps - - torch.cuda.synchronize() - e2e_tic = time.perf_counter() - - class LoadModelContext: - def __init__(ctx, model_name, alloc_shape=None, release_model=False): - ctx.model_name = model_name - ctx.release_model = release_model - ctx.alloc_shape = alloc_shape - def __enter__(ctx): - self.activateEngines(ctx.model_name, alloc_shape=ctx.alloc_shape) - def __exit__(ctx, exc_type, exc_val, exc_tb): - self.deactivateEngines(ctx.model_name, release_model=ctx.release_model) - - # Release model opportunistically in TensorRT pipeline only in low VRAM mode - release_model = self.low_vram and not self.torch_inference - with torch.inference_mode(), torch.autocast("cuda"), trt.Runtime(TRT_LOGGER): - with LoadModelContext('clip-imgfe', release_model=release_model), LoadModelContext('clip-vis', release_model=release_model): - self.profile_start('clip', color='green') - image_embeddings = self._encode_image(input_image, num_videos_per_prompt, self.do_classifier_free_guidance) - self.profile_stop('clip') - # NOTE Stable Diffusion Video was conditioned on fps - 1 - fps = fps - 1 - - self.profile_start('preprocess', color='pink') - input_image = self.image_processor.preprocess(input_image, height=image_height, width=image_width).to(self.device) - noise = randn_tensor(input_image.shape, generator=self.generator, device=input_image.device, dtype=input_image.dtype) - input_image = input_image + noise_aug_strength * noise - self.profile_stop('preprocess') - - # TODO - # assert self.torch_models['vae-temp'].dtype == torch.float32 - - with LoadModelContext('vae-temp'): - self.profile_start('vae_encoder', color='red') - image_latents = self._encode_vae_image(input_image, self.device, num_videos_per_prompt, self.do_classifier_free_guidance) - image_latents = image_latents.to(image_embeddings.dtype) - self.profile_stop('vae_encoder') - - # Repeat the image latents for each frame so we can concatenate them with the noise - # image_latents [batch, channels, height, width] ->[batch, num_frames, channels, height, width] - image_latents = image_latents.unsqueeze(1).repeat(1, self.num_frames, 1, 1, 1) - - # Get Added Time IDs - added_time_ids = self._get_add_time_ids( - fps, - motion_bucket_id, - noise_aug_strength, - image_embeddings.dtype, - batch_size, - num_videos_per_prompt, - self.do_classifier_free_guidance, - ) - added_time_ids = added_time_ids.to(self.device) - - # Prepare timesteps - self.scheduler.set_timesteps(denoising_steps, device=self.device) - timesteps = self.scheduler.timesteps - - # Prepare latent variables - latents = self.prepare_latents( - batch_size * num_videos_per_prompt, - self.num_frames, - 8, # TODO: num_channels_latents = unet.config.in_channels - image_height, - image_width, - image_embeddings.dtype, - input_image.device, - None, # pre-generated latents - ) - - # Prepare guidance scale - guidance_scale = torch.linspace(self.min_guidance_scale, self.max_guidance_scale, self.num_frames).unsqueeze(0) - guidance_scale = guidance_scale.to(self.device, latents.dtype) - guidance_scale = guidance_scale.repeat(batch_size * num_videos_per_prompt, 1) - guidance_scale = _append_dims(guidance_scale, latents.ndim) - - # Denoising loop - num_warmup_steps = len(timesteps) - denoising_steps * self.scheduler.order - unet_shape_dict = self.models['unet-temp'].get_shape_dict(batch_size, image_height, image_width) - with LoadModelContext('unet-temp', alloc_shape=unet_shape_dict, release_model=release_model), tqdm(total=denoising_steps) as progress_bar: - self.profile_start('denoise', color='blue') - for i, t in enumerate(timesteps): - # expand the latents if we are doing classifier free guidance - latent_model_input = torch.cat([latents] * 2) if self.do_classifier_free_guidance else latents - latent_model_input = self.scheduler.scale_model_input(latent_model_input, t) - - # Concatenate image_latents over channels dimention - latent_model_input = torch.cat([latent_model_input, image_latents], dim=2) - - # predict the noise residual - if self.torch_fallback['unet-temp']: - noise_pred = self.torch_models['unet-temp']( - latent_model_input, - t, - encoder_hidden_states=image_embeddings, - added_time_ids=added_time_ids, - return_dict=False, - )[0] - else: - params = { - "sample": latent_model_input, - "timestep": t, - "encoder_hidden_states": image_embeddings, - "added_time_ids": added_time_ids, - } - noise_pred = self.runEngine('unet-temp', params)['latent'] - - # perform guidance - if self.do_classifier_free_guidance: - noise_pred_uncond, noise_pred_cond = noise_pred.chunk(2) - noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_cond - noise_pred_uncond) - - # compute the previous noisy sample x_t -> x_t-1 - latents = self.scheduler.step(noise_pred, t, latents).prev_sample - - if i == len(timesteps) - 1 or ((i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0): - progress_bar.update() - self.profile_stop('denoise') - - with torch.inference_mode(), trt.Runtime(TRT_LOGGER), LoadModelContext('vae-temp'): - self.profile_start('vae', color='red') - self.torch_models['vae-temp'].to(dtype=torch.float16) - frames = self.decode_latents(latents, self.num_frames, self.decode_chunk_size) - frames = image_module.tensor2vid(frames, self.image_processor, output_type="pil") - self.profile_stop('vae') - - torch.cuda.synchronize() - - if warmup: - return - - e2e_toc = time.perf_counter() - walltime_ms = (e2e_toc - e2e_tic) * 1000. - self.print_summary(denoising_steps, walltime_ms, batch_size, len(frames[0])) - if save_video: - self.save_video(frames[0], self.pipeline_type.name.lower(), self.seed) - - return frames, walltime_ms - - def run(self, input_image, height, width, batch_size, batch_count, num_warmup_runs, use_cuda_graph, **kwargs): - num_warmup_runs = max(1, num_warmup_runs) if use_cuda_graph else num_warmup_runs - if num_warmup_runs > 0: - print("[I] Warming up ..") - for _ in range(num_warmup_runs): - self.infer(input_image, height, width, warmup=True) - - for _ in range(batch_count): - print("[I] Running StableDiffusion pipeline") - if self.nvtx_profile: - cudart.cudaProfilerStart() - self.infer(input_image, height, width, warmup=False) - if self.nvtx_profile: - cudart.cudaProfilerStop() diff --git a/demo/Diffusion/demo_diffusion/pipeline/type.py b/demo/Diffusion/demo_diffusion/pipeline/type.py deleted file mode 100644 index d011afefc..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/type.py +++ /dev/null @@ -1,68 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import enum - - -class PIPELINE_TYPE(enum.Enum): - TXT2IMG = enum.auto() - IMG2IMG = enum.auto() - IMG2VID = enum.auto() - TXT2VID = enum.auto() - CONTROLNET = enum.auto() - XL_CONTROLNET = enum.auto() - XL_BASE = enum.auto() - XL_REFINER = enum.auto() - CASCADE_PRIOR = enum.auto() - CASCADE_DECODER = enum.auto() - VIDEO2WORLD = enum.auto() - - def is_txt2img(self): - return self in (self.TXT2IMG, self.CONTROLNET) - - def is_img2img(self): - return self == self.IMG2IMG - - def is_img2vid(self): - return self == self.IMG2VID - - def is_txt2vid(self): - return self == self.TXT2VID - - def is_controlnet(self): - return self in (self.CONTROLNET, self.XL_CONTROLNET) - - def is_sd_xl_base(self): - return self in (self.XL_BASE, self.XL_CONTROLNET) - - def is_sd_xl_refiner(self): - return self == self.XL_REFINER - - def is_sd_xl(self): - return self.is_sd_xl_base() or self.is_sd_xl_refiner() - - def is_cascade_prior(self): - return self == self.CASCADE_PRIOR - - def is_cascade_decoder(self): - return self == self.CASCADE_DECODER - - def is_cascade(self): - return self.is_cascade_prior() or self.is_cascade_decoder() - - def is_video2world(self): - return self == self.VIDEO2WORLD diff --git a/demo/Diffusion/demo_diffusion/pipeline/wan_pipeline.py b/demo/Diffusion/demo_diffusion/pipeline/wan_pipeline.py deleted file mode 100644 index ba7ebc7b2..000000000 --- a/demo/Diffusion/demo_diffusion/pipeline/wan_pipeline.py +++ /dev/null @@ -1,841 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import argparse -import gc -import html -import os -import pathlib -import random -import re -import time -from typing import Any, Callable, Dict, List, Optional, Union - -import tensorrt as trt -import torch -from cuda.bindings import runtime as cudart -from diffusers.utils.torch_utils import randn_tensor -from PIL import Image -from tqdm.auto import tqdm - -try: - import ftfy - FTFY_AVAILABLE = True -except ImportError: - FTFY_AVAILABLE = False - -import demo_diffusion.engine as engine_module -import demo_diffusion.image as image_module -import demo_diffusion.path as path_module -from demo_diffusion.model import ( - T5Model, - WanTransformerModel, - AutoencoderKLWanModel, - make_tokenizer, -) -from demo_diffusion.pipeline.diffusion_pipeline import DiffusionPipeline -from demo_diffusion.pipeline.type import PIPELINE_TYPE - -TRT_LOGGER = trt.Logger(trt.Logger.ERROR) - -# Copied from https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/wan/pipeline_wan.py#L78 -def basic_clean(text): - if FTFY_AVAILABLE: - text = ftfy.fix_text(text) - text = html.unescape(html.unescape(text)) - return text.strip() - -# Copied from https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/wan/pipeline_wan.py#L84 -def whitespace_clean(text): - text = re.sub(r"\s+", " ", text) - text = text.strip() - return text - -# Copied from https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/wan/pipeline_wan.py#L90 -def prompt_clean(text): - text = whitespace_clean(basic_clean(text)) - return text - - -class WanPipeline(DiffusionPipeline): - """ - Application showcasing the acceleration of Wan 2.2 T2V pipeline using Nvidia TensorRT. - """ - - _callback_tensor_inputs = ["latents", "prompt_embeds", "negative_prompt_embeds"] - - def __init__( - self, - dd_path, - version='wan2.2-t2v-a14b', - pipeline_type=PIPELINE_TYPE.TXT2VID, - boundary_ratio: float = 0.875, - guidance_scale: float = 4.0, - guidance_scale_2: float = 3.0, - t5_weight_streaming_budget_percentage=None, - transformer_weight_streaming_budget_percentage=None, - **kwargs - ): - """ - Initializes the Wan T2V pipeline. - - Args: - dd_path (load_module.DDPath): - DDPath object that contains all paths used in DemoDiffusion - version (str): - The version of the pipeline. Should be [wan2.2-t2v-a14b] - pipeline_type (PIPELINE_TYPE): - Type of current pipeline (TXT2VID) - boundary_ratio (float, defaults to 0.875): - Ratio of total timesteps to use as the boundary for switching between transformers - in two-stage denoising. Transformer handles high-noise stages (timesteps >= boundary) - and transformer_2 handles low-noise stages (timesteps < boundary). - Wan 2.2 T2V always uses two-stage denoising. - guidance_scale (float): - Guidance scale for high-noise stage (transformer). Wan default: 4.0 - guidance_scale_2 (float): - Guidance scale for low-noise stage (transformer_2). Wan default: 3.0 - t5_weight_streaming_budget_percentage (`int`, defaults to None): - Weight streaming budget as a percentage of the size of total streamable weights for the T5 model. - transformer_weight_streaming_budget_percentage (`int`, defaults to None): - Weight streaming budget as a percentage of the size of total streamable weights for the transformer models. - """ - super().__init__( - dd_path=dd_path, - version=version, - pipeline_type=pipeline_type, - scheduler="UniPC", - bf16=True, - text_encoder_weight_streaming_budget_percentage=t5_weight_streaming_budget_percentage, - denoiser_weight_streaming_budget_percentage=transformer_weight_streaming_budget_percentage, - **kwargs - ) - - # Validate boundary_ratio (required for Wan 2.2 two-stage denoising) - if boundary_ratio is None or not (0.0 < boundary_ratio < 1.0): - raise ValueError( - f"`boundary_ratio` must be between 0.0 and 1.0, got {boundary_ratio}" - ) - - self.boundary_ratio = boundary_ratio - self.guidance_scale = guidance_scale - self.guidance_scale_2 = guidance_scale_2 - - self.vae_scale_factor_temporal = 4 - self.vae_scale_factor_spatial = 8 - - self.opt_image_height = 720 - self.opt_image_width = 1280 - self.opt_num_frames = 81 - self.max_sequence_length = 512 - - @classmethod - def FromArgs(cls, args: argparse.Namespace, pipeline_type: PIPELINE_TYPE) -> 'WanPipeline': - """Factory method to construct a WanPipeline object from parsed arguments.""" - - MAX_BATCH_SIZE = 1 # Wan always uses batch size 1 - DEVICE = "cuda" - - dd_path = path_module.resolve_path( - cls.get_model_names(pipeline_type), args, pipeline_type, cls._get_pipeline_uid(args.version) - ) - - return cls( - dd_path=dd_path, - version=args.version, - pipeline_type=pipeline_type, - boundary_ratio=args.boundary_ratio, - denoising_steps=args.denoising_steps, - guidance_scale=args.guidance_scale, - guidance_scale_2=args.guidance_scale_2, - t5_weight_streaming_budget_percentage=args.t5_ws_percentage if hasattr(args, 't5_ws_percentage') else None, - transformer_weight_streaming_budget_percentage=args.transformer_ws_percentage if hasattr(args, 'transformer_ws_percentage') else None, - max_batch_size=MAX_BATCH_SIZE, - device=DEVICE, - output_dir=args.output_dir, - hf_token=args.hf_token, - verbose=args.verbose, - nvtx_profile=args.nvtx_profile, - use_cuda_graph=args.use_cuda_graph, - framework_model_dir=args.framework_model_dir, - low_vram=args.low_vram, - torch_inference=args.torch_inference, - torch_fallback=args.torch_fallback if hasattr(args, 'torch_fallback') else None, - weight_streaming=args.ws if hasattr(args, 'ws') else False, - ) - - @classmethod - def get_model_names(cls, pipeline_type: PIPELINE_TYPE, controlnet_type: str = None) -> List[str]: - """Return a list of model names used by this pipeline. - - Overrides: - DiffusionPipeline.get_model_names - """ - return ["text_encoder", "transformer", "transformer_2", "vae_decoder"] - - def download_onnx_models(self, model_name: str, model_config: dict[str, Any]) -> None: - raise NotImplementedError( - "Pre-exported Wan ONNX models are not available for download. " - "Export ONNX models locally using the provided export script." - ) - - def _initialize_models(self, framework_model_dir, int8=False, fp8=False, fp4=False): - self.tokenizer = make_tokenizer( - self.version, - self.pipeline_type, - self.hf_token, - framework_model_dir, - subfolder='tokenizer', - tokenizer_type='t5' - ) - - models_args = { - 'version': self.version, - 'pipeline': self.pipeline_type, - 'device': self.device, - 'hf_token': self.hf_token, - 'verbose': self.verbose, - 'framework_model_dir': framework_model_dir, - 'max_batch_size': 1 - } - - if "text_encoder" in self.stages: - self.models['text_encoder'] = T5Model( - **models_args, - fp16=False, - bf16=True, - text_maxlen=self.max_sequence_length, - weight_streaming=self.weight_streaming, - weight_streaming_budget_percentage=self.text_encoder_weight_streaming_budget_percentage, - use_attention_mask=True, - ) - - if "transformer" in self.stages: - self.models['transformer'] = WanTransformerModel( - **models_args, - subfolder='transformer', - fp16=False, - bf16=True, - text_maxlen=self.max_sequence_length, - num_frames=self.opt_num_frames, - height=self.opt_image_height, - width=self.opt_image_width, - weight_streaming=self.weight_streaming, - weight_streaming_budget_percentage=self.denoiser_weight_streaming_budget_percentage, - ) - - if "transformer_2" in self.stages: - self.models['transformer_2'] = WanTransformerModel( - **models_args, - subfolder='transformer_2', - fp16=False, - bf16=True, - text_maxlen=self.max_sequence_length, - num_frames=self.opt_num_frames, - height=self.opt_image_height, - width=self.opt_image_width, - weight_streaming=self.weight_streaming, - weight_streaming_budget_percentage=self.denoiser_weight_streaming_budget_percentage, - ) - - if "vae_decoder" in self.stages: - self.models['vae_decoder'] = AutoencoderKLWanModel( - **models_args, - ) - - self.config['vae_decoder_torch_fallback'] = True - - def load_resources(self, image_height, image_width, batch_size, seed): - """Override to create additional 'denoise' event for combined transformer timing.""" - super().load_resources(image_height, image_width, batch_size, seed) - # additional event for combined denoising timing (both transformers) - self.events['denoise'] = [cudart.cudaEventCreate()[1], cudart.cudaEventCreate()[1]] - - def print_summary(self, denoising_steps, walltime_ms, batch_size, num_frames): - print("|----------------------|--------------|") - print("| {:^20} | {:^12} |".format("Module", "Latency")) - print("|----------------------|--------------|") - - # calculate transformer timings from combined denoise event - total_denoise_time = cudart.cudaEventElapsedTime(self.events['denoise'][0], self.events['denoise'][1])[1] - transformer_steps_map = { - 'transformer': self.transformer_steps if (self.transformer_steps > 0 and self.transformer_2_steps > 0) else denoising_steps, - 'transformer_2': self.transformer_2_steps if self.transformer_2_steps > 0 else 0 - } - - for stage in self.stages: - if stage in transformer_steps_map and transformer_steps_map[stage] > 0: - steps = transformer_steps_map[stage] - time_ms = total_denoise_time * (steps / denoising_steps) - stage_label = f"{stage} x {steps}" - elif stage in transformer_steps_map: - continue # skip transformer_2 if unused - else: - time_ms = cudart.cudaEventElapsedTime(self.events[stage][0], self.events[stage][1])[1] - stage_label = stage - - print("| {:^20} | {:>9.2f} ms |".format(stage_label, time_ms)) - - print("|----------------------|--------------|") - print("| {:^20} | {:>9.2f} ms |".format("Pipeline", walltime_ms)) - print("|----------------------|--------------|") - print("Throughput: {:.2f} videos/min ({} frames)".format(batch_size * 60000.0 / walltime_ms, num_frames)) - - def save_video(self, frames, pipeline, prompt, seed): - if isinstance(prompt, list): - prompt_prefix = ''.join(set([p.replace(' ','_')[:10] for p in prompt])) - else: - prompt_prefix = prompt.replace(' ','_')[:10] - - seed_str = str(seed) if seed is not None else 'random' - precision = 'bf16' if self.bf16 else 'fp16' if self.fp16 else 'fp32' - video_name_prefix = '-'.join([pipeline, prompt_prefix, precision, seed_str, str(random.randint(1000,9999))]) - video_name_suffix = 'torch' if self.torch_inference else 'trt' - video_path = video_name_prefix+'-'+video_name_suffix+'.gif' - full_path = os.path.join(self.output_dir, video_path) - print(f"Saving video to: {full_path}") - frames[0].save(full_path, save_all=True, optimize=False, append_images=frames[1:], loop=0) - - # Adapted from https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/wan/pipeline_wan.py#L198 - def encode_prompt( - self, - prompt: Union[str, List[str]], - negative_prompt: Optional[Union[str, List[str]]] = None, - do_classifier_free_guidance: bool = True, - num_videos_per_prompt: int = 1, - prompt_embeds: Optional[torch.Tensor] = None, - negative_prompt_embeds: Optional[torch.Tensor] = None, - max_sequence_length: int = 226, - device: Optional[torch.device] = None, - dtype: Optional[torch.dtype] = None, - ): - r""" - Encodes the prompt into text encoder hidden states. - - Implementation modeled from diffusers Wan pipeline, adapted for TensorRT. - - Args: - prompt (`str` or `List[str]`, *optional*): - prompt to be encoded - negative_prompt (`str` or `List[str]`, *optional*): - The prompt or prompts not to guide the image generation. If not defined, one has to pass - `negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is - less than `1`). - do_classifier_free_guidance (`bool`, *optional*, defaults to `True`): - Whether to use classifier free guidance or not. - num_videos_per_prompt (`int`, *optional*, defaults to 1): - Number of videos that should be generated per prompt. torch device to place the resulting embeddings on - prompt_embeds (`torch.Tensor`, *optional*): - Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not - provided, text embeddings will be generated from `prompt` input argument. - negative_prompt_embeds (`torch.Tensor`, *optional*): - Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt - weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input - argument. - max_sequence_length (`int`, defaults to `226`): - Maximum sequence length for text encoder. - device: (`torch.device`, *optional*): - torch device - dtype: (`torch.dtype`, *optional*): - torch dtype - """ - self.profile_start('text_encoder', color='green') - - device = device or self._execution_device - - prompt = [prompt] if isinstance(prompt, str) else prompt - if prompt is not None: - batch_size = len(prompt) - else: - batch_size = prompt_embeds.shape[0] - - if prompt_embeds is None: - prompt_embeds = self._get_t5_prompt_embeds( - prompt=prompt, - num_videos_per_prompt=num_videos_per_prompt, - max_sequence_length=max_sequence_length, - device=device, - dtype=dtype, - ) - - if do_classifier_free_guidance and negative_prompt_embeds is None: - negative_prompt = negative_prompt or "" - negative_prompt = batch_size * [negative_prompt] if isinstance(negative_prompt, str) else negative_prompt - - if prompt is not None and type(prompt) is not type(negative_prompt): - raise TypeError( - f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !=" - f" {type(prompt)}." - ) - elif batch_size != len(negative_prompt): - raise ValueError( - f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:" - f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches" - " the batch size of `prompt`." - ) - - negative_prompt_embeds = self._get_t5_prompt_embeds( - prompt=negative_prompt, - num_videos_per_prompt=num_videos_per_prompt, - max_sequence_length=max_sequence_length, - device=device, - dtype=dtype, - ) - - self.profile_stop('text_encoder') - return prompt_embeds, negative_prompt_embeds - - def denoise_latents( - self, - latents: torch.Tensor, - prompt_embeds: torch.Tensor, - negative_prompt_embeds: Optional[torch.Tensor], - timesteps: torch.Tensor, - guidance_scale: float, - guidance_scale_2: float, - transformer_dtype: torch.dtype, - num_warmup_steps: int, - attention_kwargs: Optional[Dict[str, Any]] = None, - callback_on_step_end: Optional[Callable] = None, - callback_on_step_end_tensor_inputs: Optional[List[str]] = None, - warmup: bool = False, - ) -> torch.Tensor: - boundary_timestep = self.boundary_ratio * self.scheduler.config.num_train_timesteps - self.profile_start('denoise', color='blue') - - timestep_stages = [] - for i, t in enumerate(timesteps): - if t >= boundary_timestep: - timestep_stages.append((i, t, 'transformer', guidance_scale)) - else: - timestep_stages.append((i, t, 'transformer_2', guidance_scale_2)) - - stage_groups = [] - if timestep_stages: - current_group = { - 'transformer': timestep_stages[0][2], - 'guidance_scale': timestep_stages[0][3], - 'timesteps': [(timestep_stages[0][0], timestep_stages[0][1])] - } - - for i, t, transformer_name, gs in timestep_stages[1:]: - if transformer_name == current_group['transformer']: - current_group['timesteps'].append((i, t)) - else: - stage_groups.append(current_group) - current_group = { - 'transformer': transformer_name, - 'guidance_scale': gs, - 'timesteps': [(i, t)] - } - stage_groups.append(current_group) - - self.transformer_steps = sum(len(g['timesteps']) for g in stage_groups if g['transformer'] == 'transformer') - self.transformer_2_steps = sum(len(g['timesteps']) for g in stage_groups if g['transformer'] == 'transformer_2') - - with tqdm(total=len(timesteps)) as progress_bar: - for stage_group in stage_groups: - transformer_name = stage_group['transformer'] - current_guidance_scale = stage_group['guidance_scale'] - - with self.model_memory_manager([transformer_name], low_vram=self.low_vram): - for step_index, t in stage_group['timesteps']: - latent_model_input = latents.to(transformer_dtype) - timestep = t.expand(latent_model_input.shape[0]) - - if self.torch_inference or self.torch_fallback[transformer_name]: - current_model = self.torch_models[transformer_name] - - noise_pred_cond = current_model( - hidden_states=latent_model_input, - timestep=timestep, - encoder_hidden_states=prompt_embeds, - attention_kwargs=attention_kwargs, - return_dict=False, - )[0] - - if self.do_classifier_free_guidance: - noise_pred_uncond = current_model( - hidden_states=latent_model_input, - timestep=timestep, - encoder_hidden_states=negative_prompt_embeds, - attention_kwargs=attention_kwargs, - return_dict=False, - )[0] - - noise_pred = noise_pred_uncond + current_guidance_scale * (noise_pred_cond - noise_pred_uncond) - else: - noise_pred = noise_pred_cond - else: - if self.do_classifier_free_guidance: - params_cond = { - "hidden_states": latent_model_input, - "timestep": timestep, - "encoder_hidden_states": prompt_embeds, - } - - # conditional engine call - output_cond = self.run_engine(transformer_name, params_cond)['denoised_latents'] - - noise_pred_cond = output_cond.clone() - - params_uncond = { - "hidden_states": latent_model_input, - "timestep": timestep, - "encoder_hidden_states": negative_prompt_embeds, - } - - # unconditional engine call - output_uncond = self.run_engine(transformer_name, params_uncond)['denoised_latents'] - - noise_pred_uncond = output_uncond.clone() - - # Apply classifier-free guidance - noise_pred = noise_pred_uncond + current_guidance_scale * (noise_pred_cond - noise_pred_uncond) - else: - # No CFG - params = { - "hidden_states": latent_model_input, - "timestep": timestep, - "encoder_hidden_states": prompt_embeds, - } - noise_pred = self.run_engine(transformer_name, params)['denoised_latents'] - - latents = self.scheduler.step(noise_pred, t, latents, return_dict=False)[0] - - if callback_on_step_end is not None: - callback_kwargs = {} - for k in callback_on_step_end_tensor_inputs: - callback_kwargs[k] = locals()[k] - callback_outputs = callback_on_step_end(self, step_index, t, callback_kwargs) - - latents = callback_outputs.pop("latents", latents) - prompt_embeds = callback_outputs.pop("prompt_embeds", prompt_embeds) - negative_prompt_embeds = callback_outputs.pop("negative_prompt_embeds", negative_prompt_embeds) - - if step_index == len(timesteps) - 1 or ((step_index + 1) > num_warmup_steps and (step_index + 1) % self.scheduler.order == 0): - progress_bar.update() - - self.profile_stop('denoise') - return latents - - # Adapted from https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/wan/pipeline_wan.py#L324 - def prepare_latents( - self, - batch_size: int, - num_channels_latents: int = 16, - height: int = 720, - width: int = 1280, - num_frames: int = 81, - dtype: Optional[torch.dtype] = None, - device: Optional[torch.device] = None, - generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None, - latents: Optional[torch.Tensor] = None, - ) -> torch.Tensor: - if latents is not None: - return latents.to(device=device, dtype=dtype) - - num_latent_frames = (num_frames - 1) // self.vae_scale_factor_temporal + 1 - shape = ( - batch_size, - num_channels_latents, - num_latent_frames, - int(height) // self.vae_scale_factor_spatial, - int(width) // self.vae_scale_factor_spatial, - ) - if isinstance(generator, list) and len(generator) != batch_size: - raise ValueError( - f"You have passed a list of generators of length {len(generator)}, but requested an effective batch" - f" size of {batch_size}. Make sure the batch size matches the length of the generators." - ) - - if generator is None and hasattr(self, 'generator'): - generator = self.generator - - latents = randn_tensor(shape, generator=generator, device=device, dtype=dtype) - return latents - - # Copied from https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/wan/pipeline_wan.py#L279 - def check_inputs( - self, - prompt, - negative_prompt, - height, - width, - prompt_embeds=None, - negative_prompt_embeds=None, - callback_on_step_end_tensor_inputs=None, - guidance_scale_2=None, - ): - if height % 16 != 0 or width % 16 != 0: - raise ValueError(f"`height` and `width` have to be divisible by 16 but are {height} and {width}.") - - if callback_on_step_end_tensor_inputs is not None: - pass - - if prompt is not None and prompt_embeds is not None: - raise ValueError( - f"Cannot forward both `prompt`: {prompt} and `prompt_embeds`: {prompt_embeds}. Please make sure to" - " only forward one of the two." - ) - elif negative_prompt is not None and negative_prompt_embeds is not None: - raise ValueError( - f"Cannot forward both `negative_prompt`: {negative_prompt} and `negative_prompt_embeds`: {negative_prompt_embeds}. Please make sure to" - " only forward one of the two." - ) - elif prompt is None and prompt_embeds is None: - raise ValueError( - "Provide either `prompt` or `prompt_embeds`. Cannot leave both `prompt` and `prompt_embeds` undefined." - ) - elif prompt is not None and (not isinstance(prompt, str) and not isinstance(prompt, list)): - raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}") - elif negative_prompt is not None and ( - not isinstance(negative_prompt, str) and not isinstance(negative_prompt, list) - ): - raise ValueError(f"`negative_prompt` has to be of type `str` or `list` but is {type(negative_prompt)}") - - # Adapted from https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/wan/pipeline_wan.py#L157 - def _get_t5_prompt_embeds( - self, - prompt: Union[str, List[str]] = None, - num_videos_per_prompt: int = 1, - max_sequence_length: int = 226, - device: Optional[torch.device] = None, - dtype: Optional[torch.dtype] = None, - encoder: str = "text_encoder", - ): - device = device or self._execution_device - dtype = dtype or (self.torch_models[encoder].dtype if self.torch_fallback.get(encoder) and encoder in self.torch_models else torch.float32) - - prompt = [prompt] if isinstance(prompt, str) else prompt - prompt = [prompt_clean(u) for u in prompt] - batch_size = len(prompt) - - text_inputs = self.tokenizer( - prompt, - padding="max_length", - max_length=max_sequence_length, - truncation=True, - add_special_tokens=True, - return_attention_mask=True, - return_tensors="pt", - ) - text_input_ids, mask = text_inputs.input_ids, text_inputs.attention_mask - seq_lens = mask.gt(0).sum(dim=1).long() - - if self.torch_inference or self.torch_fallback[encoder]: - outputs = self.torch_models[encoder](text_input_ids.to(device), mask.to(device)) - prompt_embeds = outputs.last_hidden_state.clone() - else: - outputs = self.run_engine(encoder, { - "input_ids": text_input_ids.to(device), - "attention_mask": mask.to(device) - }) - prompt_embeds = outputs['text_embeddings'].clone() - - prompt_embeds = prompt_embeds.to(dtype=dtype, device=device) - - prompt_embeds = [u[:v] for u, v in zip(prompt_embeds, seq_lens)] - prompt_embeds = torch.stack( - [torch.cat([u, u.new_zeros(max_sequence_length - u.size(0), u.size(1))]) for u in prompt_embeds], dim=0 - ) - - _, seq_len, _ = prompt_embeds.shape - prompt_embeds = prompt_embeds.repeat(1, num_videos_per_prompt, 1) - prompt_embeds = prompt_embeds.view(batch_size * num_videos_per_prompt, seq_len, -1) - - return prompt_embeds - - @property - def _execution_device(self): - return self.device - - @property - def do_classifier_free_guidance(self): - return self.guidance_scale > 1.0 - - @property - def num_timesteps(self): - return self._num_timesteps - - def decode_latents(self, latents, num_frames): - self.profile_start('vae_decoder', color='red') - - vae_config = self.models['vae_decoder'].config - z_dim = vae_config.get("z_dim", 16) - - vae_dtype = torch.float32 - latents = latents.to(vae_dtype) - - latents_mean = ( - torch.tensor(vae_config.get("latents_mean")) - .view(1, z_dim, 1, 1, 1) - .to(latents.device, latents.dtype) - ) - latents_std = 1.0 / torch.tensor(vae_config.get("latents_std")).view(1, z_dim, 1, 1, 1).to( - latents.device, latents.dtype - ) - - latents = latents / latents_std + latents_mean - - frames = self.torch_models['vae_decoder'].decode(latents, return_dict=False)[0] - - self.profile_stop('vae_decoder') - return frames - - def postprocess(self, video: torch.Tensor, output_type: str = "pil"): - # Convert [F, C, H, W] -> [F, H, W, C] - video = video.permute(0, 2, 3, 1) - # Convert to list of PIL Images - video = (video + 1.0) / 2.0 - video = torch.clamp(video, 0.0, 1.0) - video = (video * 255.0).to(torch.uint8).cpu().numpy() - pil_frames = [Image.fromarray(frame) for frame in video] - return pil_frames - - def infer( - self, - prompt: Union[str, List[str]], - negative_prompt: Optional[Union[str, List[str]]] = None, - height: int = 720, - width: int = 1280, - num_frames: int = 81, - num_inference_steps: int = 40, - num_videos_per_prompt: int = 1, - generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None, - latents: Optional[torch.Tensor] = None, - prompt_embeds: Optional[torch.Tensor] = None, - negative_prompt_embeds: Optional[torch.Tensor] = None, - output_type: str = "pil", - attention_kwargs: Optional[Dict[str, Any]] = None, - callback_on_step_end: Optional[Union[Callable, Any]] = None, - callback_on_step_end_tensor_inputs: List[str] = ["latents"], - max_sequence_length: int = 512, - warmup: bool = False, - save_video: bool = True, - ): - """ - Run the Wan text-to-video diffusion pipeline. - """ - - self.check_inputs( - prompt, - negative_prompt, - height, - width, - prompt_embeds, - negative_prompt_embeds, - callback_on_step_end_tensor_inputs, - self.guidance_scale_2, - ) - - if num_frames % self.vae_scale_factor_temporal != 1: - print(f"[W] `num_frames - 1` has to be divisible by {self.vae_scale_factor_temporal}. Rounding to the nearest number.") - num_frames = num_frames // self.vae_scale_factor_temporal * self.vae_scale_factor_temporal + 1 - num_frames = max(num_frames, 1) - - device = self._execution_device - batch_size = 1 - - with torch.inference_mode(), trt.Runtime(TRT_LOGGER): - torch.cuda.synchronize() - e2e_tic = time.perf_counter() - - with self.model_memory_manager(["text_encoder"], low_vram=self.low_vram): - prompt_embeds, negative_prompt_embeds = self.encode_prompt( - prompt=prompt, - negative_prompt=negative_prompt, - do_classifier_free_guidance=self.do_classifier_free_guidance, - num_videos_per_prompt=num_videos_per_prompt, - prompt_embeds=prompt_embeds, - negative_prompt_embeds=negative_prompt_embeds, - max_sequence_length=max_sequence_length, - device=device, - ) - - transformer_dtype = torch.bfloat16 - prompt_embeds = prompt_embeds.to(transformer_dtype) - if negative_prompt_embeds is not None: - negative_prompt_embeds = negative_prompt_embeds.to(transformer_dtype) - - self.scheduler.set_timesteps(num_inference_steps, device=self.device) - timesteps = self.scheduler.timesteps - - num_channels_latents = self.models["transformer"].config.get("in_channels", 16) - latents = self.prepare_latents( - batch_size * num_videos_per_prompt, - num_channels_latents, - height, - width, - num_frames, - torch.float32, - device, - generator, - latents, - ) - - num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order - self._num_timesteps = len(timesteps) - - latents = self.denoise_latents( - latents=latents, - prompt_embeds=prompt_embeds, - negative_prompt_embeds=negative_prompt_embeds, - timesteps=timesteps, - guidance_scale=self.guidance_scale, - guidance_scale_2=self.guidance_scale_2, - transformer_dtype=transformer_dtype, - num_warmup_steps=num_warmup_steps, - attention_kwargs=attention_kwargs, - callback_on_step_end=callback_on_step_end, - callback_on_step_end_tensor_inputs=callback_on_step_end_tensor_inputs, - warmup=warmup, - ) - - with self.model_memory_manager(["vae_decoder"], low_vram=self.low_vram): - video_raw = self.decode_latents(latents, num_frames) - video = image_module.tensor2vid(video_raw, self, output_type="pil") - - torch.cuda.synchronize() - e2e_toc = time.perf_counter() - - walltime_ms = (e2e_toc - e2e_tic) * 1000.0 - if not warmup: - self.print_summary(num_inference_steps, walltime_ms, batch_size, num_frames) - if save_video: - self.save_video(video[0], self.pipeline_type.name.lower(), prompt, self.seed) - - return video, walltime_ms - - def run(self, prompt, height, width, num_frames, batch_size, batch_count, num_warmup_runs, use_cuda_graph, **kwargs): - if self.low_vram and self.use_cuda_graph: - print("[W] Using low_vram, use_cuda_graph will be disabled") - self.use_cuda_graph = False - - num_warmup_runs = max(1, num_warmup_runs) if use_cuda_graph else num_warmup_runs - if num_warmup_runs > 0: - print("[I] Warming up ..") - for _ in range(num_warmup_runs): - self.infer(prompt, height=height, width=width, num_frames=num_frames, warmup=True, **kwargs) - - for _ in range(batch_count): - print("[I] Running Wan T2V pipeline") - if self.nvtx_profile: - cudart.cudaProfilerStart() - self.infer(prompt, height=height, width=width, num_frames=num_frames, warmup=False, **kwargs) - if self.nvtx_profile: - cudart.cudaProfilerStop() diff --git a/demo/Diffusion/demo_diffusion/utils_modelopt.py b/demo/Diffusion/demo_diffusion/utils_modelopt.py deleted file mode 100755 index 70e484bb3..000000000 --- a/demo/Diffusion/demo_diffusion/utils_modelopt.py +++ /dev/null @@ -1,853 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import os -import re -from collections import defaultdict -from random import choice, shuffle -from typing import Set - -import modelopt.torch.quantization as mtq -import numpy as np -import onnx_graphsurgeon as gs -import torch -import torch.nn.functional as F -from diffusers.models.attention_processor import ( - Attention, - AttnProcessor, - FluxAttnProcessor2_0, -) -from diffusers.models.lora import LoRACompatibleConv, LoRACompatibleLinear -from modelopt.torch.quantization import utils as quant_utils -from modelopt.torch.quantization.calib.max import MaxCalibrator -from PIL import Image -from torch.utils.data import Dataset, Sampler - -import onnx - -USE_PEFT = True -try: - from peft.tuners.lora.layer import Conv2d as PEFTLoRAConv2d - from peft.tuners.lora.layer import Linear as PEFTLoRALinear -except ModuleNotFoundError: - USE_PEFT = False - -class PercentileCalibrator(MaxCalibrator): - def __init__(self, num_bits=8, axis=None, unsigned=False, track_amax=False, **kwargs): - super().__init__(num_bits, axis, unsigned, track_amax) - self.percentile = kwargs["percentile"] - self.total_step = kwargs["total_step"] - self.collect_method = kwargs["collect_method"] - self.data = {} - self.i = 0 - - def collect(self, x): - """Tracks the absolute max of all tensors. - - Args: - x: A tensor - - Raises: - RuntimeError: If amax shape changes - """ - # Swap axis to reduce. - axis = self._axis if isinstance(self._axis, (list, tuple)) else [self._axis] - # Handle negative axis. - axis = [x.dim() + i if isinstance(i, int) and i < 0 else i for i in axis] - reduce_axis = [] - for i in range(x.dim()): - if i not in axis: - reduce_axis.append(i) - local_amax = quant_utils.reduce_amax(x, axis=reduce_axis).detach() - _cur_step = self.i % self.total_step - if _cur_step not in self.data.keys(): - self.data[_cur_step] = local_amax - else: - if self.collect_method == "global_min": - self.data[_cur_step] = torch.min(self.data[_cur_step], local_amax) - elif self.collect_method == "min-max" or self.collect_method == "mean-max": - self.data[_cur_step] = torch.max(self.data[_cur_step], local_amax) - else: - self.data[_cur_step] += local_amax - if self._track_amax: - raise NotImplementedError - self.i += 1 - - def compute_amax(self): - """Return the absolute max of all tensors collected.""" - up_lim = int(self.total_step * self.percentile) - if self.collect_method == "min-mean": - amaxs_values = [self.data[i] / self.total_step for i in range(0, up_lim)] - else: - amaxs_values = [self.data[i] for i in range(0, up_lim)] - if self.collect_method == "mean-max": - act_amax = torch.vstack(amaxs_values).mean(axis=0)[0] - else: - act_amax = torch.vstack(amaxs_values).min(axis=0)[0] - self._calib_amax = act_amax - return self._calib_amax - - def __str__(self): - s = "PercentileCalibrator" - return s.format(**self.__dict__) - - def __repr__(self): - s = "PercentileCalibrator(" - s += super(MaxCalibrator, self).__repr__() - s += " calib_amax={_calib_amax}" - if self._track_amax: - s += " amaxs={_amaxs}" - s += ")" - return s.format(**self.__dict__) - -def filter_func(name): - pattern = re.compile( - r".*(time_emb_proj|time_embedding|conv_in|conv_out|conv_shortcut|add_embedding|pos_embed|time_text_embed|context_embedder|norm_out|proj_out).*" - ) - return pattern.match(name) is not None - -def filter_func_no_proj_out(name): # used for Flux - pattern = re.compile( - r".*(time_emb_proj|time_embedding|conv_in|conv_out|conv_shortcut|add_embedding|pos_embed|time_text_embed|context_embedder|norm_out|x_embedder).*" - ) - return pattern.match(name) is not None - -def quantize_lvl(model_id, backbone, quant_level=2.5, linear_only=False, enable_conv_3d=True): - """ - We should disable the unwanted quantizer when exporting the onnx - Because in the current modelopt setting, it will load the quantizer amax for all the layers even - if we didn't add that unwanted layer into the config during the calibration - """ - for name, module in backbone.named_modules(): - if isinstance(module, torch.nn.Conv2d): - if linear_only: - module.input_quantizer.disable() - module.weight_quantizer.disable() - else: - module.input_quantizer.enable() - module.weight_quantizer.enable() - elif isinstance(module, torch.nn.Linear): - if ( - (quant_level >= 2 and "ff.net" in name) - or (quant_level >= 2.5 and ("to_q" in name or "to_k" in name or "to_v" in name)) - or quant_level >= 3 - ) and name != "proj_out": # Disable the final output layer from flux model - module.input_quantizer.enable() - module.weight_quantizer.enable() - else: - module.input_quantizer.disable() - module.weight_quantizer.disable() - elif isinstance(module, torch.nn.Conv3d) and not enable_conv_3d: - """ - Error: Torch bug, ONNX export failed due to unknown kernel shape in QuantConv3d. - TRT_FP8QuantizeLinear and TRT_FP8DequantizeLinear operations in UNetSpatioTemporalConditionModel for svd - cause issues. Inputs on different devices (CUDA vs CPU) may contribute to the problem. - """ - module.input_quantizer.disable() - module.weight_quantizer.disable() - elif isinstance(module, Attention): - # TRT only supports FP8 MHA with head_size % 16 == 0. - head_size = int(module.inner_dim / module.heads) - if quant_level >= 4 and head_size % 16 == 0: - module.q_bmm_quantizer.enable() - module.k_bmm_quantizer.enable() - module.v_bmm_quantizer.enable() - module.softmax_quantizer.enable() - if model_id.startswith("flux.1"): - if name.startswith("transformer_blocks"): - module.bmm2_output_quantizer.enable() - else: - module.bmm2_output_quantizer.disable() - setattr(module, "_disable_fp8_mha", False) - else: - module.q_bmm_quantizer.disable() - module.k_bmm_quantizer.disable() - module.v_bmm_quantizer.disable() - module.softmax_quantizer.disable() - module.bmm2_output_quantizer.disable() - setattr(module, "_disable_fp8_mha", True) - -def fp8_mha_disable(backbone, quantized_mha_output: bool = True): - def mha_filter_func(name): - pattern = re.compile( - r".*(q_bmm_quantizer|k_bmm_quantizer|v_bmm_quantizer|softmax_quantizer).*" - if quantized_mha_output - else r".*(q_bmm_quantizer|k_bmm_quantizer|v_bmm_quantizer|softmax_quantizer|bmm2_output_quantizer).*" - ) - return pattern.match(name) is not None - - if hasattr(F, "scaled_dot_product_attention"): - mtq.disable_quantizer(backbone, mha_filter_func) - -def get_int8_config( - model, - quant_level=3, - alpha=0.8, - percentile=1.0, - num_inference_steps=20, - collect_method="min-mean", -): - quant_config = { - "quant_cfg": { - "*lm_head*": {"enable": False}, - "*output_layer*": {"enable": False}, - "*output_quantizer": {"enable": False}, - "default": {"num_bits": 8, "axis": None}, - }, - "algorithm": {"method": "smoothquant", "alpha": alpha}, - } - for name, module in model.named_modules(): - w_name = f"{name}*weight_quantizer" - i_name = f"{name}*input_quantizer" - - if w_name in quant_config["quant_cfg"].keys() or i_name in quant_config["quant_cfg"].keys(): - continue - if filter_func(name): - continue - if isinstance(module, (torch.nn.Linear, LoRACompatibleLinear)): - if ( - (quant_level >= 2 and "ff.net" in name) - or (quant_level >= 2.5 and ("to_q" in name or "to_k" in name or "to_v" in name)) - or quant_level == 3 - ): - quant_config["quant_cfg"][w_name] = {"num_bits": 8, "axis": 0} - quant_config["quant_cfg"][i_name] = {"num_bits": 8, "axis": -1} - elif isinstance(module, (torch.nn.Conv2d, LoRACompatibleConv)): - quant_config["quant_cfg"][w_name] = {"num_bits": 8, "axis": 0} - quant_config["quant_cfg"][i_name] = { - "num_bits": 8, - "axis": None, - "calibrator": ( - PercentileCalibrator, - (), - { - "num_bits": 8, - "axis": None, - "percentile": percentile, - "total_step": num_inference_steps, - "collect_method": collect_method, - }, - ), - } - return quant_config - -SD_FP8_FP16_DEFAULT_CONFIG = { - "quant_cfg": { - "*weight_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "Half"}, - "*input_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "Half"}, - "*output_quantizer": {"enable": False}, - "*q_bmm_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "Half"}, - "*k_bmm_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "Half"}, - "*v_bmm_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "Half"}, - "*softmax_quantizer": { - "num_bits": (4, 3), - "axis": None, - "trt_high_precision_dtype": "Half", - }, - "default": {"enable": False}, - }, - "algorithm": "max", -} - -SD_FP8_BF16_DEFAULT_CONFIG = { - "quant_cfg": { - "*weight_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "BFloat16"}, - "*input_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "BFloat16"}, - "*output_quantizer": {"enable": False}, - "*q_bmm_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "BFloat16"}, - "*k_bmm_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "BFloat16"}, - "*v_bmm_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "BFloat16"}, - "*softmax_quantizer": { - "num_bits": (4, 3), - "axis": None, - "trt_high_precision_dtype": "BFloat16", - }, - "default": {"enable": False}, - }, - "algorithm": "max", -} - -SD_FP8_BF16_FLUX_MMDIT_BMM2_FP8_OUTPUT_CONFIG = { - "quant_cfg": { - "*weight_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "BFloat16"}, - "*input_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "BFloat16"}, - "*output_quantizer": {"enable": False}, - "*q_bmm_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "BFloat16"}, - "*k_bmm_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "BFloat16"}, - "*v_bmm_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "BFloat16"}, - "*softmax_quantizer": { - "num_bits": (4, 3), - "axis": None, - "trt_high_precision_dtype": "BFloat16", - }, - "transformer_blocks*bmm2_output_quantizer": { - "num_bits": (4, 3), - "axis": None, - "trt_high_precision_dtype": "BFloat16", - }, - "default": {"enable": False}, - }, - "algorithm": "max", -} - -SD_FP8_FP32_DEFAULT_CONFIG = { - "quant_cfg": { - "*weight_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "Float"}, - "*input_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "Float"}, - "*output_quantizer": {"enable": False}, - "*q_bmm_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "Float"}, - "*k_bmm_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "Float"}, - "*v_bmm_quantizer": {"num_bits": (4, 3), "axis": None, "trt_high_precision_dtype": "Float"}, - "*softmax_quantizer": { - "num_bits": (4, 3), - "axis": None, - "trt_high_precision_dtype": "Float", - }, - "default": {"enable": False}, - }, - "algorithm": "max", -} - -def set_fmha(denoiser, is_flux=False): - for name, module in denoiser.named_modules(): - if isinstance(module, Attention): - if is_flux: - module.set_processor(FluxAttnProcessor2_0()) - else: - module.set_processor(AttnProcessor()) - -def check_lora(model): - for name, module in model.named_modules(): - if isinstance(module, (LoRACompatibleConv, LoRACompatibleLinear)): - assert ( - module.lora_layer is None - ), f"To quantize {name}, LoRA layer should be fused/merged. Please fuse the LoRA layer before quantization." - elif USE_PEFT and isinstance(module, (PEFTLoRAConv2d, PEFTLoRALinear)): - assert ( - module.merged - ), f"To quantize {name}, LoRA layer should be fused/merged. Please fuse the LoRA layer before quantization." - -def generate_fp8_scales(unet): - # temporary solution due to a known bug in torch.onnx._dynamo_export - for _, module in unet.named_modules(): - if isinstance(module, (torch.nn.Linear, torch.nn.Conv2d)) and ( - hasattr(module.input_quantizer, "_amax") and module.input_quantizer is not None - ): - module.input_quantizer._num_bits = 8 - module.weight_quantizer._num_bits = 8 - module.input_quantizer._amax = module.input_quantizer._amax * (127 / 448.0) - module.weight_quantizer._amax = module.weight_quantizer._amax * (127 / 448.0) - elif isinstance(module, Attention) and ( - hasattr(module.q_bmm_quantizer, "_amax") - and module.q_bmm_quantizer is not None - and hasattr(module.k_bmm_quantizer, "_amax") - and module.k_bmm_quantizer is not None - and hasattr(module.v_bmm_quantizer, "_amax") - and module.v_bmm_quantizer is not None - and hasattr(module.softmax_quantizer, "_amax") - and module.softmax_quantizer is not None - ): - module.q_bmm_quantizer._num_bits = 8 - module.q_bmm_quantizer._amax = module.q_bmm_quantizer._amax * (127 / 448.0) - module.k_bmm_quantizer._num_bits = 8 - module.k_bmm_quantizer._amax = module.k_bmm_quantizer._amax * (127 / 448.0) - module.v_bmm_quantizer._num_bits = 8 - module.v_bmm_quantizer._amax = module.v_bmm_quantizer._amax * (127 / 448.0) - module.softmax_quantizer._num_bits = 8 - module.softmax_quantizer._amax = module.softmax_quantizer._amax * (127 / 448.0) - -def get_parent_nodes(node): - """ - Returns list of input producer nodes for the given node. - """ - parents = [] - for tensor in node.inputs: - # If the tensor is not a constant or graph input and has a producer, - # the producer is a parent of node `node` - if len(tensor.inputs) == 1: - parents.append(tensor.inputs[0]) - return parents - -def get_child_nodes(node): - """ - Returns list of output consumer nodes for the given node. - """ - children = [] - for tensor in node.outputs: - for consumer in tensor.outputs: # Traverse all consumer of the tensor - children.append(consumer) - return children - -def has_path_type(node, graph, path_type, is_forward, wild_card_types, path_nodes): - """ - Return pattern nodes for the given path_type. - """ - if not path_type: - # All types matched - return True - - # Check if current non-wild node type does not match the expected path type - node_type = node.op - is_match = node_type == path_type[0] - is_wild_match = node_type in wild_card_types - if not is_match and not is_wild_match: - return False - - if is_match: - path_nodes.append(node) - next_path_type = path_type[1:] - else: - next_path_type = path_type[:] - - if is_forward: - next_level_nodes = get_child_nodes(node) - else: - next_level_nodes = get_parent_nodes(node) - - # Check if any child (forward path) or parent (backward path) can match the remaining path types - for next_node in next_level_nodes: - sub_path = [] - if has_path_type(next_node, graph, next_path_type, is_forward, wild_card_types, sub_path): - path_nodes.extend(sub_path) - return True - - # Path type matches if there is no remaining types to match - return not next_path_type - -def insert_cast(graph, input_tensor, attrs): - """ - Create a cast layer using tensor as input. - """ - output_tensor = gs.Variable(name=f"{input_tensor.name}/Cast_output", dtype=attrs["to"]) - next_node_list = input_tensor.outputs.copy() - graph.layer( - op="Cast", - name=f"{input_tensor.name}/Cast", - inputs=[input_tensor], - outputs=[output_tensor], - attrs=attrs, - ) - - # use cast output as input to next node - for next_node in next_node_list: - for idx, next_input in enumerate(next_node.inputs): - if next_input.name == input_tensor.name: - next_node.inputs[idx] = output_tensor - -def cast_layernorm_io(graph): - """ - Cast LayerNormalization scale and bias inputs from FP16 to FP32. - In INT8 quantized graphs, DequantizeLinear outputs Float32 activations, - but LayerNorm scale/bias remain FP16 from the original model, causing - a type mismatch with --strongly-typed TensorRT builds. - """ - layernorm_nodes = [node for node in graph.nodes if node.op == "LayerNormalization"] - - print(f"Found {len(layernorm_nodes)} LayerNormalization nodes to fix") - for node in layernorm_nodes: - # LayerNormalization inputs: 0=X (data), 1=Scale, 2=B (bias, optional) - for i in range(1, len(node.inputs)): - input_tensor = node.inputs[i] - if input_tensor.name and hasattr(input_tensor, 'dtype') and input_tensor.dtype == np.float16: - insert_cast(graph, input_tensor=input_tensor, attrs={"to": np.float32}) - -def cast_convtranspose_io(graph): - """ - Fix ConvTranspose input/output type mismatches for strongly-typed TRT builds. - In mixed-precision graphs (e.g. BF16 Stable Cascade VQGAN), architectural FP16->FP32 - casts can leave a ConvTranspose with a FP32 activation input but FP16 kernel weights. - We cast the activation to match the kernel dtype, then cast the output back to the - original activation dtype so surrounding FP32 ops (e.g. residual Add) are unaffected. - """ - convtranspose_nodes = [node for node in graph.nodes if node.op == "ConvTranspose"] - fixed = 0 - for node in convtranspose_nodes: - if len(node.inputs) < 2: - continue - act_input = node.inputs[0] - kernel = node.inputs[1] - if act_input.dtype is None or kernel.dtype is None or act_input.dtype == kernel.dtype: - continue - orig_dtype = act_input.dtype # e.g. np.dtype('float32') - target_dtype = kernel.dtype.type # e.g. np.float16 - insert_cast(graph, input_tensor=act_input, attrs={"to": target_dtype}) - # Update the output dtype to match and cast back, so downstream FP32 ops are unaffected. - for out in node.outputs: - if out.name and out.dtype == orig_dtype: - out.dtype = target_dtype - insert_cast(graph, input_tensor=out, attrs={"to": orig_dtype.type}) - fixed += 1 - print(f"Fixed {fixed} ConvTranspose input/output type mismatches") - - -def convert_zp_fp8(onnx_graph): - """ - Convert Q/DQ zero datatype from INT8 to FP8. - """ - # Find all zero constant nodes - qdq_zero_nodes = set() - for node in onnx_graph.graph.node: - if node.op_type == "QuantizeLinear": - if len(node.input) > 2: - qdq_zero_nodes.add(node.input[2]) - - print(f"Found {len(qdq_zero_nodes)} QDQ pairs") - - # Convert zero point datatype from INT8 to FP8. - for node in onnx_graph.graph.node: - if node.output[0] in qdq_zero_nodes: - node.attribute[0].t.data_type = onnx.TensorProto.FLOAT8E4M3FN - - return onnx_graph - -def cast_resize_io(graph, output_dtype=np.float16): - """ - Add cast nodes to Resize nodes I/O because Resize needs to be run in fp32. - Inputs are cast to FP32, outputs are cast back to output_dtype (FP16 or BF16). - """ - resize_nodes = [node for node in graph.nodes if node.op == "Resize"] - - print(f"Found {len(resize_nodes)} Resize nodes to fix") - for resize_node in resize_nodes: - # Skip Resize nodes whose data input is already FP32 — no casting needed. - if resize_node.inputs[0].dtype == np.float32: - continue - for i, input_tensor in enumerate(resize_node.inputs): - SIZES_INPUT_INDEX = 3 # Optional input "sizes" at index 3 must be in INT64. Skip cast for this input. - if i != SIZES_INPUT_INDEX and input_tensor.name: - insert_cast(graph, input_tensor=input_tensor, attrs={"to": np.float32}) - for output_tensor in resize_node.outputs: - if output_tensor.name: - insert_cast(graph, input_tensor=output_tensor, attrs={"to": output_dtype}) - -def cast_fp8_mha_io(graph): - r""" - Insert three cast ops. - The first cast will be added before the input0 of MatMul to cast fp16 to fp32. - The second cast will be added before the input1 of MatMul to cast fp16 to fp32. - The third cast will be added after the output of MatMul to cast fp32 back to fp16. - Q Q - | | - DQ DQ - | | - Cast Cast - (fp16 to fp32) (fp16 to fp32) - \ / - \ / - \ / - MatMul - | - Cast (fp32 to fp16) - | - Q - | - DQ - The insertion of Cast ops in the FP8 MHA part actually forbids the MHAs to run - with FP16 accumulation because TensorRT only has FP32 accumulation kernels for FP8 MHAs. - """ - # Find FP8 MHA pattern. - # Match FP8 MHA: Q -> DQ -> BMM1 -> (Mul/Div) -> (Add) -> Softmax -> (Cast) -> Q -> DQ -> BMM2 -> Q -> DQ - softmax_bmm1_chain_type = ["Softmax", "MatMul", "DequantizeLinear", "QuantizeLinear"] - softmax_bmm2_chain_type = [ - "Softmax", - "QuantizeLinear", - "DequantizeLinear", - "MatMul", - "QuantizeLinear", - "DequantizeLinear", - ] - wild_card_types = [ - "Div", - "Mul", - "ConstMul", - "Add", - "BiasAdd", - "Reshape", - "Transpose", - "Flatten", - "Cast", - ] - - fp8_mha_partitions = [] - for node in graph.nodes: - if node.op == "Softmax": - fp8_mha_partition = [] - if has_path_type( - node, graph, softmax_bmm1_chain_type, False, wild_card_types, fp8_mha_partition - ) and has_path_type( - node, graph, softmax_bmm2_chain_type, True, wild_card_types, fp8_mha_partition - ): - if ( - len(fp8_mha_partition) == 10 - and fp8_mha_partition[1].op == "MatMul" - and fp8_mha_partition[7].op == "MatMul" - ): - fp8_mha_partitions.append(fp8_mha_partition) - - print(f"Found {len(fp8_mha_partitions)} FP8 attentions") - - # Insert Cast nodes for BMM1 and BMM2. - for fp8_mha_partition in fp8_mha_partitions: - bmm1_node = fp8_mha_partition[1] - insert_cast(graph, input_tensor=bmm1_node.inputs[0], attrs={"to": np.float32}) - insert_cast(graph, input_tensor=bmm1_node.inputs[1], attrs={"to": np.float32}) - insert_cast(graph, input_tensor=bmm1_node.outputs[0], attrs={"to": np.float16}) - - bmm2_node = fp8_mha_partition[7] - insert_cast(graph, input_tensor=bmm2_node.inputs[0], attrs={"to": np.float32}) - insert_cast(graph, input_tensor=bmm2_node.inputs[1], attrs={"to": np.float32}) - insert_cast(graph, input_tensor=bmm2_node.outputs[0], attrs={"to": np.float16}) - -def set_quant_precision(quant_config, precision: str = "Half"): - for key in quant_config["quant_cfg"]: - if "trt_high_precision_dtype" in quant_config["quant_cfg"][key]: - quant_config["quant_cfg"][key]["trt_high_precision_dtype"] = precision - -def convert_fp16_io(graph): - """ - Convert graph I/O to FP16. - """ - for input_tensor in graph.inputs: - input_tensor.dtype = onnx.TensorProto.FLOAT16 - for output_tensor in graph.outputs: - output_tensor.dtype = onnx.TensorProto.FLOAT16 - - -def random_resize(cur_size: int): - """ - Randomly selects a new resolution for an image based on its current aspect ratio. - - This function determines the current aspect ratio of an image, selects a new aspect ratio - from predefined choices depending on whether the current aspect ratio is square, - portrait, or landscape, and returns the corresponding resolution from a provided mapping. - - Parameters: - cur_size (int): A tuple (width, height) representing the current resolution of the image. - resolution_to_aspects (dict[float, tuple[int, int]]): A mapping of aspect ratios (floats) - to their corresponding resolutions as tuples of (width, height). - - Returns: - tuple[int, int]: A tuple (new_width, new_height) representing the newly selected resolution. - - Raises: - KeyError: If the chosen aspect ratio is not present in the `resolution_to_aspects` dictionary. - - Notes: - - For square images (aspect ratio = 1), the function selects from aspect ratios 1.25, 0.8, 1.5, and 0.667. - - For landscape images (aspect ratio > 1), the function selects from aspect ratios 1.778, 1.25, and 1.5. - - For portrait images (aspect ratio < 1), the function selects from aspect ratios 0.563, 0.8, and 0.667. - """ - resolution_to_aspects = { - 1.0: (1024, 1024), - 1.778: (768, 1344), - 0.563: (1344, 768), - 1.25: (896, 1152), - 0.8: (1152, 896), - 1.5: (832, 1216), - 0.667: (1216, 832), - } - - cur_aspect_ratio = round(cur_size[1] / cur_size[0], 3) - - if cur_aspect_ratio == 1: - new_aspect_ratio = choice((1.25, 0.8, 1.5, 0.667)) - new_res = resolution_to_aspects[new_aspect_ratio] - elif cur_aspect_ratio > 1: - new_aspect_ratio = choice((1.778, 1.25, 1.5)) - new_res = resolution_to_aspects[new_aspect_ratio] - else: - # cur_aspect_ratio < 1 - new_aspect_ratio = choice((0.563, 0.8, 0.667)) - new_res = resolution_to_aspects[new_aspect_ratio] - - return new_res - - -class PromptImageDataset(Dataset): - def __init__( - self, - root_dir, - ): - """ - Args: - root_dir (str): Directory with all the images and the prompt file. - """ - self.root_dir = root_dir - self.possible_resolutions = {1024, 768, 1344, 896, 832, 1216} - self.global_idx_template = "{} | {} | {}" - - self.prompts_by_size = defaultdict(list) - self.images_by_size = defaultdict(list) - self.images = [] - self.prompts = [] - self.images_size = [] - # self.global_idx_2_group = dict() - # self.global_idx_to_group_idx = dict() - self.group_to_global_idx = {} - - for idx, file in enumerate(os.listdir(os.path.join(self.root_dir, "prompts"))): - if not file.endswith(".txt"): - continue - file_name = os.path.splitext(file)[0] - image_path = os.path.join( - self.root_dir, - "inputs", - f"{file_name}.png", - ) - - with Image.open(image_path) as img, open(os.path.join(self.root_dir, "prompts", file), "r") as f: - prompt = "\n".join(f.readlines()) - - std_img_size = ( - self.closest_value(img.size[0], self.possible_resolutions), - self.closest_value(img.size[1], self.possible_resolutions), - ) - - self.images_by_size[std_img_size].append(image_path) - self.prompts_by_size[std_img_size].append(prompt) - - self.images.append(image_path) - self.prompts.append(prompt) - self.images_size.append(std_img_size) - - # create a unique key that map group and index inside the group to a global index - in_group_idx = len(self.images_by_size[std_img_size]) - 1 - group_idx_key = self.global_idx_template.format(std_img_size[0], std_img_size[1], in_group_idx) - self.group_to_global_idx[group_idx_key] = len(self.images) - 1 - - assert len(self.images) == len(self.prompts) - assert len(self.images) == len(self.group_to_global_idx) - - @staticmethod - def closest_value(target: int, candidates: Set[int]): - """ - Find the closest value to the target from a set of candidate values. - - Args: - target (int): The integer to compare against. - candidates (set): A set of integers as candidates. - - Returns: - int: The closest value from the candidates. - """ - if not candidates: - raise ValueError("The candidates set cannot be empty.") - - # Use the min function with a key that computes the absolute difference - return min(candidates, key=lambda x: abs(x - target)) - - def __len__(self): - return len(self.images) - - def __getitem__(self, idx): - """ - Returns: - image (Tensor): Transformed image. - prompt (str): Corresponding text prompt. - """ - if torch.is_tensor(idx): - idx = idx.tolist() - - prompt = self.prompts[idx] - image = self.images[idx] - image_size = self.images_size[idx] - return image, prompt, image_size - - -class SameSizeSampler(Sampler): - def __init__(self, dataset: PromptImageDataset, batch_size: int): - """ - Custom sampler that creates batches of images with the same size - - Args: - dataset (SameSizeImageDataset): Dataset to sample from - batch_size (int): Number of images per batch - """ - super().__init__(dataset) - self.dataset = dataset - self.batch_size = batch_size - - # Prepare size groups with indices - self.size_groups = {} - for size, image_paths in self.dataset.images_by_size.items(): - # Create a list of indices for this size group - self.size_groups[size] = list(range(len(image_paths))) - - def __iter__(self): - """ - Iteration method that yields indices for batches of same-size images - """ - # Create a copy of size groups to shuffle - size_groups_copy = {std_img_size: indices.copy() for std_img_size, indices in self.size_groups.items()} - - # Shuffle each size group - for std_img_size, indices in size_groups_copy.items(): - shuffle(indices) - - # Iterate through size groups - for std_img_size, indices in size_groups_copy.items(): - # Batch indices of the same size - for i in range(0, len(indices), self.batch_size): - # Yield batch indices for this size - batch_group_idxs = indices[i : min(i + self.batch_size, len(indices))] - for in_group_idx in batch_group_idxs: - group_idx_key = self.dataset.global_idx_template.format( - std_img_size[0], std_img_size[1], in_group_idx - ) - batch_global_idx = self.dataset.group_to_global_idx[group_idx_key] - # batch_global_idxs.append(batch_global_idx) - yield batch_global_idx - - def __len__(self): - """ - Total number of batches - """ - return len(self.dataset.images) // self.batch_size - - -def custom_collate(data): - """ - Custom collate function to handle batches of same-size images - - Args: - dataset (SameSizeImageDataset): Dataset instance - batch (list): List of global indices - - Returns: - tuple: Batched images and their size - """ - # Group images by their size - images, prompts, image_sizes = tuple(map(list, zip(*data))) - assert len(images) > 0 - new_img_size = random_resize(image_sizes[0]) - batch_images = [] - for image in images: - with Image.open(image) as image: - image = image.convert("RGB").resize(size=new_img_size, resample=Image.LANCZOS) - image = np.array(image) - image = np.transpose(image, axes=(-1, 0, 1)) - image = torch.from_numpy(image).float() / 127.5 - 1.0 - batch_images.append(image) - - batch_images = torch.stack(batch_images, dim=0) - return batch_images, prompts - - -def infinite_dataloader(dataloader): - while True: - for batch in dataloader: - yield batch diff --git a/demo/Diffusion/demo_diffusion/utils_sd3/__init__.py b/demo/Diffusion/demo_diffusion/utils_sd3/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/demo/Diffusion/demo_diffusion/utils_sd3/mmdit.py b/demo/Diffusion/demo_diffusion/utils_sd3/mmdit.py deleted file mode 100644 index 0e1a669f9..000000000 --- a/demo/Diffusion/demo_diffusion/utils_sd3/mmdit.py +++ /dev/null @@ -1,641 +0,0 @@ -# MIT License - -# Copyright (c) 2024 Stability AI - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import math -from typing import Dict, Optional - -import numpy as np -import torch -import torch.nn as nn -from einops import rearrange, repeat - -from demo_diffusion.utils_sd3.other_impls import Mlp, attention - - -class PatchEmbed(nn.Module): - """ 2D Image to Patch Embedding""" - def __init__( - self, - img_size: Optional[int] = 224, - patch_size: int = 16, - in_chans: int = 3, - embed_dim: int = 768, - flatten: bool = True, - bias: bool = True, - strict_img_size: bool = True, - dynamic_img_pad: bool = False, - dtype=None, - device=None, - ): - super().__init__() - self.patch_size = (patch_size, patch_size) - if img_size is not None: - self.img_size = (img_size, img_size) - self.grid_size = tuple([s // p for s, p in zip(self.img_size, self.patch_size)]) - self.num_patches = self.grid_size[0] * self.grid_size[1] - else: - self.img_size = None - self.grid_size = None - self.num_patches = None - - # flatten spatial dim and transpose to channels last, kept for bwd compat - self.flatten = flatten - self.strict_img_size = strict_img_size - self.dynamic_img_pad = dynamic_img_pad - - self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size, bias=bias, dtype=dtype, device=device) - - def forward(self, x): - B, C, H, W = x.shape - x = self.proj(x) - if self.flatten: - x = x.flatten(2).transpose(1, 2) # NCHW -> NLC - return x - - -def modulate(x, shift, scale): - if shift is None: - shift = torch.zeros_like(scale) - return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1) - - -################################################################################# -# Sine/Cosine Positional Embedding Functions # -################################################################################# - - -def get_2d_sincos_pos_embed(embed_dim, grid_size, cls_token=False, extra_tokens=0, scaling_factor=None, offset=None): - """ - grid_size: int of the grid height and width - return: - pos_embed: [grid_size*grid_size, embed_dim] or [1+grid_size*grid_size, embed_dim] (w/ or w/o cls_token) - """ - grid_h = np.arange(grid_size, dtype=np.float32) - grid_w = np.arange(grid_size, dtype=np.float32) - grid = np.meshgrid(grid_w, grid_h) # here w goes first - grid = np.stack(grid, axis=0) - if scaling_factor is not None: - grid = grid / scaling_factor - if offset is not None: - grid = grid - offset - grid = grid.reshape([2, 1, grid_size, grid_size]) - pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid) - if cls_token and extra_tokens > 0: - pos_embed = np.concatenate([np.zeros([extra_tokens, embed_dim]), pos_embed], axis=0) - return pos_embed - - -def get_2d_sincos_pos_embed_from_grid(embed_dim, grid): - assert embed_dim % 2 == 0 - # use half of dimensions to encode grid_h - emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0]) # (H*W, D/2) - emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1]) # (H*W, D/2) - emb = np.concatenate([emb_h, emb_w], axis=1) # (H*W, D) - return emb - - -def get_1d_sincos_pos_embed_from_grid(embed_dim, pos): - """ - embed_dim: output dimension for each position - pos: a list of positions to be encoded: size (M,) - out: (M, D) - """ - assert embed_dim % 2 == 0 - omega = np.arange(embed_dim // 2, dtype=np.float64) - omega /= embed_dim / 2.0 - omega = 1.0 / 10000**omega # (D/2,) - pos = pos.reshape(-1) # (M,) - out = np.einsum("m,d->md", pos, omega) # (M, D/2), outer product - emb_sin = np.sin(out) # (M, D/2) - emb_cos = np.cos(out) # (M, D/2) - return np.concatenate([emb_sin, emb_cos], axis=1) # (M, D) - - -################################################################################# -# Embedding Layers for Timesteps and Class Labels # -################################################################################# - - -class TimestepEmbedder(nn.Module): - """Embeds scalar timesteps into vector representations.""" - - def __init__(self, hidden_size, frequency_embedding_size=256, dtype=None, device=None): - super().__init__() - self.mlp = nn.Sequential( - nn.Linear(frequency_embedding_size, hidden_size, bias=True, dtype=dtype, device=device), - nn.SiLU(), - nn.Linear(hidden_size, hidden_size, bias=True, dtype=dtype, device=device), - ) - self.frequency_embedding_size = frequency_embedding_size - - @staticmethod - def timestep_embedding(t, dim, max_period=10000): - """ - Create sinusoidal timestep embeddings. - :param t: a 1-D Tensor of N indices, one per batch element. - These may be fractional. - :param dim: the dimension of the output. - :param max_period: controls the minimum frequency of the embeddings. - :return: an (N, D) Tensor of positional embeddings. - """ - half = dim // 2 - freqs = torch.exp( - -math.log(max_period) - * torch.arange(start=0, end=half, dtype=torch.float32) - / half - ).to(device=t.device) - args = t[:, None].float() * freqs[None] - embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1) - if dim % 2: - embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1) - if torch.is_floating_point(t): - embedding = embedding.to(dtype=t.dtype) - return embedding - - def forward(self, t, dtype, **kwargs): - t_freq = self.timestep_embedding(t, self.frequency_embedding_size).to(dtype) - t_emb = self.mlp(t_freq) - return t_emb - - -class VectorEmbedder(nn.Module): - """Embeds a flat vector of dimension input_dim""" - - def __init__(self, input_dim: int, hidden_size: int, dtype=None, device=None): - super().__init__() - self.mlp = nn.Sequential( - nn.Linear(input_dim, hidden_size, bias=True, dtype=dtype, device=device), - nn.SiLU(), - nn.Linear(hidden_size, hidden_size, bias=True, dtype=dtype, device=device), - ) - - def forward(self, x: torch.Tensor) -> torch.Tensor: - return self.mlp(x) - - -################################################################################# -# Core DiT Model # -################################################################################# - - -def split_qkv(qkv, head_dim): - qkv = qkv.reshape(qkv.shape[0], qkv.shape[1], 3, -1, head_dim).movedim(2, 0) - return qkv[0], qkv[1], qkv[2] - -def optimized_attention(qkv, num_heads): - return attention(qkv[0], qkv[1], qkv[2], num_heads) - -class SelfAttention(nn.Module): - ATTENTION_MODES = ("xformers", "torch", "torch-hb", "math", "debug") - - def __init__( - self, - dim: int, - num_heads: int = 8, - qkv_bias: bool = False, - qk_scale: Optional[float] = None, - attn_mode: str = "xformers", - pre_only: bool = False, - qk_norm: Optional[str] = None, - rmsnorm: bool = False, - dtype=None, - device=None, - ): - super().__init__() - self.num_heads = num_heads - self.head_dim = dim // num_heads - - self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias, dtype=dtype, device=device) - if not pre_only: - self.proj = nn.Linear(dim, dim, dtype=dtype, device=device) - assert attn_mode in self.ATTENTION_MODES - self.attn_mode = attn_mode - self.pre_only = pre_only - - if qk_norm == "rms": - self.ln_q = RMSNorm(self.head_dim, elementwise_affine=True, eps=1.0e-6, dtype=dtype, device=device) - self.ln_k = RMSNorm(self.head_dim, elementwise_affine=True, eps=1.0e-6, dtype=dtype, device=device) - elif qk_norm == "ln": - self.ln_q = nn.LayerNorm(self.head_dim, elementwise_affine=True, eps=1.0e-6, dtype=dtype, device=device) - self.ln_k = nn.LayerNorm(self.head_dim, elementwise_affine=True, eps=1.0e-6, dtype=dtype, device=device) - elif qk_norm is None: - self.ln_q = nn.Identity() - self.ln_k = nn.Identity() - else: - raise ValueError(qk_norm) - - def pre_attention(self, x: torch.Tensor): - B, L, C = x.shape - qkv = self.qkv(x) - q, k, v = split_qkv(qkv, self.head_dim) - q = self.ln_q(q).reshape(q.shape[0], q.shape[1], -1) - k = self.ln_k(k).reshape(q.shape[0], q.shape[1], -1) - return (q, k, v) - - def post_attention(self, x: torch.Tensor) -> torch.Tensor: - assert not self.pre_only - x = self.proj(x) - return x - - def forward(self, x: torch.Tensor) -> torch.Tensor: - (q, k, v) = self.pre_attention(x) - x = attention(q, k, v, self.num_heads) - x = self.post_attention(x) - return x - - -class RMSNorm(torch.nn.Module): - def __init__( - self, dim: int, elementwise_affine: bool = False, eps: float = 1e-6, device=None, dtype=None - ): - """ - Initialize the RMSNorm normalization layer. - Args: - dim (int): The dimension of the input tensor. - eps (float, optional): A small value added to the denominator for numerical stability. Default is 1e-6. - Attributes: - eps (float): A small value added to the denominator for numerical stability. - weight (nn.Parameter): Learnable scaling parameter. - """ - super().__init__() - self.eps = eps - self.learnable_scale = elementwise_affine - if self.learnable_scale: - self.weight = nn.Parameter(torch.empty(dim, device=device, dtype=dtype)) - else: - self.register_parameter("weight", None) - - def _norm(self, x): - """ - Apply the RMSNorm normalization to the input tensor. - Args: - x (torch.Tensor): The input tensor. - Returns: - torch.Tensor: The normalized tensor. - """ - return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) - - def forward(self, x): - """ - Forward pass through the RMSNorm layer. - Args: - x (torch.Tensor): The input tensor. - Returns: - torch.Tensor: The output tensor after applying RMSNorm. - """ - x = self._norm(x) - if self.learnable_scale: - return x * self.weight.to(device=x.device, dtype=x.dtype) - else: - return x - - -class SwiGLUFeedForward(nn.Module): - def __init__( - self, - dim: int, - hidden_dim: int, - multiple_of: int, - ffn_dim_multiplier: Optional[float] = None, - ): - """ - Initialize the FeedForward module. - - Args: - dim (int): Input dimension. - hidden_dim (int): Hidden dimension of the feedforward layer. - multiple_of (int): Value to ensure hidden dimension is a multiple of this value. - ffn_dim_multiplier (float, optional): Custom multiplier for hidden dimension. Defaults to None. - - Attributes: - w1 (ColumnParallelLinear): Linear transformation for the first layer. - w2 (RowParallelLinear): Linear transformation for the second layer. - w3 (ColumnParallelLinear): Linear transformation for the third layer. - - """ - super().__init__() - hidden_dim = int(2 * hidden_dim / 3) - # custom dim factor multiplier - if ffn_dim_multiplier is not None: - hidden_dim = int(ffn_dim_multiplier * hidden_dim) - hidden_dim = multiple_of * ((hidden_dim + multiple_of - 1) // multiple_of) - - self.w1 = nn.Linear(dim, hidden_dim, bias=False) - self.w2 = nn.Linear(hidden_dim, dim, bias=False) - self.w3 = nn.Linear(dim, hidden_dim, bias=False) - - def forward(self, x): - return self.w2(nn.functional.silu(self.w1(x)) * self.w3(x)) - - -class DismantledBlock(nn.Module): - """A DiT block with gated adaptive layer norm (adaLN) conditioning.""" - - ATTENTION_MODES = ("xformers", "torch", "torch-hb", "math", "debug") - - def __init__( - self, - hidden_size: int, - num_heads: int, - mlp_ratio: float = 4.0, - attn_mode: str = "xformers", - qkv_bias: bool = False, - pre_only: bool = False, - rmsnorm: bool = False, - scale_mod_only: bool = False, - swiglu: bool = False, - qk_norm: Optional[str] = None, - dtype=None, - device=None, - **block_kwargs, - ): - super().__init__() - assert attn_mode in self.ATTENTION_MODES - if not rmsnorm: - self.norm1 = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device) - else: - self.norm1 = RMSNorm(hidden_size, elementwise_affine=False, eps=1e-6) - self.attn = SelfAttention(dim=hidden_size, num_heads=num_heads, qkv_bias=qkv_bias, attn_mode=attn_mode, pre_only=pre_only, qk_norm=qk_norm, rmsnorm=rmsnorm, dtype=dtype, device=device) - if not pre_only: - if not rmsnorm: - self.norm2 = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device) - else: - self.norm2 = RMSNorm(hidden_size, elementwise_affine=False, eps=1e-6) - mlp_hidden_dim = int(hidden_size * mlp_ratio) - if not pre_only: - if not swiglu: - self.mlp = Mlp(in_features=hidden_size, hidden_features=mlp_hidden_dim, act_layer=nn.GELU(approximate="tanh"), dtype=dtype, device=device) - else: - self.mlp = SwiGLUFeedForward(dim=hidden_size, hidden_dim=mlp_hidden_dim, multiple_of=256) - self.scale_mod_only = scale_mod_only - if not scale_mod_only: - n_mods = 6 if not pre_only else 2 - else: - n_mods = 4 if not pre_only else 1 - self.adaLN_modulation = nn.Sequential(nn.SiLU(), nn.Linear(hidden_size, n_mods * hidden_size, bias=True, dtype=dtype, device=device)) - self.pre_only = pre_only - - def pre_attention(self, x: torch.Tensor, c: torch.Tensor): - assert x is not None, "pre_attention called with None input" - if not self.pre_only: - if not self.scale_mod_only: - shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaLN_modulation(c).chunk(6, dim=1) - else: - shift_msa = None - shift_mlp = None - scale_msa, gate_msa, scale_mlp, gate_mlp = self.adaLN_modulation(c).chunk(4, dim=1) - qkv = self.attn.pre_attention(modulate(self.norm1(x), shift_msa, scale_msa)) - return qkv, (x, gate_msa, shift_mlp, scale_mlp, gate_mlp) - else: - if not self.scale_mod_only: - shift_msa, scale_msa = self.adaLN_modulation(c).chunk(2, dim=1) - else: - shift_msa = None - scale_msa = self.adaLN_modulation(c) - qkv = self.attn.pre_attention(modulate(self.norm1(x), shift_msa, scale_msa)) - return qkv, None - - def post_attention(self, attn, x, gate_msa, shift_mlp, scale_mlp, gate_mlp): - assert not self.pre_only - x = x + gate_msa.unsqueeze(1) * self.attn.post_attention(attn) - x = x + gate_mlp.unsqueeze(1) * self.mlp(modulate(self.norm2(x), shift_mlp, scale_mlp)) - return x - - def forward(self, x: torch.Tensor, c: torch.Tensor) -> torch.Tensor: - assert not self.pre_only - (q, k, v), intermediates = self.pre_attention(x, c) - attn = attention(q, k, v, self.attn.num_heads) - return self.post_attention(attn, *intermediates) - - -def block_mixing(context, x, context_block, x_block, c): - assert context is not None, "block_mixing called with None context" - context_qkv, context_intermediates = context_block.pre_attention(context, c) - - x_qkv, x_intermediates = x_block.pre_attention(x, c) - - o = [] - for t in range(3): - o.append(torch.cat((context_qkv[t], x_qkv[t]), dim=1)) - q, k, v = tuple(o) - - attn = attention(q, k, v, x_block.attn.num_heads) - context_attn, x_attn = (attn[:, : context_qkv[0].shape[1]], attn[:, context_qkv[0].shape[1] :]) - - if not context_block.pre_only: - context = context_block.post_attention(context_attn, *context_intermediates) - else: - context = None - x = x_block.post_attention(x_attn, *x_intermediates) - return context, x - - -class JointBlock(nn.Module): - """just a small wrapper to serve as a fsdp unit""" - - def __init__(self, *args, **kwargs): - super().__init__() - pre_only = kwargs.pop("pre_only") - qk_norm = kwargs.pop("qk_norm", None) - self.context_block = DismantledBlock(*args, pre_only=pre_only, qk_norm=qk_norm, **kwargs) - self.x_block = DismantledBlock(*args, pre_only=False, qk_norm=qk_norm, **kwargs) - - def forward(self, *args, **kwargs): - return block_mixing(*args, context_block=self.context_block, x_block=self.x_block, **kwargs) - - -class FinalLayer(nn.Module): - """ - The final layer of DiT. - """ - - def __init__(self, hidden_size: int, patch_size: int, out_channels: int, total_out_channels: Optional[int] = None, dtype=None, device=None): - super().__init__() - self.norm_final = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device) - self.linear = ( - nn.Linear(hidden_size, patch_size * patch_size * out_channels, bias=True, dtype=dtype, device=device) - if (total_out_channels is None) - else nn.Linear(hidden_size, total_out_channels, bias=True, dtype=dtype, device=device) - ) - self.adaLN_modulation = nn.Sequential(nn.SiLU(), nn.Linear(hidden_size, 2 * hidden_size, bias=True, dtype=dtype, device=device)) - - def forward(self, x: torch.Tensor, c: torch.Tensor) -> torch.Tensor: - shift, scale = self.adaLN_modulation(c).chunk(2, dim=1) - x = modulate(self.norm_final(x), shift, scale) - x = self.linear(x) - return x - - -class MMDiT(nn.Module): - """Diffusion model with a Transformer backbone.""" - - def __init__( - self, - input_size: int = 32, - patch_size: int = 2, - in_channels: int = 4, - depth: int = 28, - mlp_ratio: float = 4.0, - learn_sigma: bool = False, - adm_in_channels: Optional[int] = None, - context_embedder_config: Optional[Dict] = None, - register_length: int = 0, - attn_mode: str = "torch", - rmsnorm: bool = False, - scale_mod_only: bool = False, - swiglu: bool = False, - out_channels: Optional[int] = None, - pos_embed_scaling_factor: Optional[float] = None, - pos_embed_offset: Optional[float] = None, - pos_embed_max_size: Optional[int] = None, - num_patches = None, - qk_norm: Optional[str] = None, - qkv_bias: bool = True, - dtype = None, - device = None, - ): - super().__init__() - self.dtype = dtype - self.learn_sigma = learn_sigma - self.in_channels = in_channels - default_out_channels = in_channels * 2 if learn_sigma else in_channels - self.out_channels = out_channels if out_channels is not None else default_out_channels - self.patch_size = patch_size - self.pos_embed_scaling_factor = pos_embed_scaling_factor - self.pos_embed_offset = pos_embed_offset - self.pos_embed_max_size = pos_embed_max_size - - # apply magic --> this defines a head_size of 64 - hidden_size = 64 * depth - num_heads = depth - - self.num_heads = num_heads - - self.x_embedder = PatchEmbed(input_size, patch_size, in_channels, hidden_size, bias=True, strict_img_size=self.pos_embed_max_size is None, dtype=dtype, device=device) - self.t_embedder = TimestepEmbedder(hidden_size, dtype=dtype, device=device) - - if adm_in_channels is not None: - assert isinstance(adm_in_channels, int) - self.y_embedder = VectorEmbedder(adm_in_channels, hidden_size, dtype=dtype, device=device) - - self.context_embedder = nn.Identity() - if context_embedder_config is not None: - if context_embedder_config["target"] == "torch.nn.Linear": - self.context_embedder = nn.Linear(**context_embedder_config["params"], dtype=dtype, device=device) - - self.register_length = register_length - if self.register_length > 0: - self.register = nn.Parameter(torch.randn(1, register_length, hidden_size, dtype=dtype, device=device)) - - # num_patches = self.x_embedder.num_patches - # Will use fixed sin-cos embedding: - # just use a buffer already - if num_patches is not None: - self.register_buffer( - "pos_embed", - torch.zeros(1, num_patches, hidden_size, dtype=dtype, device=device), - ) - else: - self.pos_embed = None - - self.joint_blocks = nn.ModuleList( - [ - JointBlock(hidden_size, num_heads, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, attn_mode=attn_mode, pre_only=i == depth - 1, rmsnorm=rmsnorm, scale_mod_only=scale_mod_only, swiglu=swiglu, qk_norm=qk_norm, dtype=dtype, device=device) - for i in range(depth) - ] - ) - - self.final_layer = FinalLayer(hidden_size, patch_size, self.out_channels, dtype=dtype, device=device) - - def cropped_pos_embed(self, hw): - assert self.pos_embed_max_size is not None - p = self.x_embedder.patch_size[0] - h, w = hw - # patched size - h = h // p - w = w // p - assert h <= self.pos_embed_max_size, (h, self.pos_embed_max_size) - assert w <= self.pos_embed_max_size, (w, self.pos_embed_max_size) - top = (self.pos_embed_max_size - h) // 2 - left = (self.pos_embed_max_size - w) // 2 - spatial_pos_embed = rearrange( - self.pos_embed, - "1 (h w) c -> 1 h w c", - h=self.pos_embed_max_size, - w=self.pos_embed_max_size, - ) - spatial_pos_embed = spatial_pos_embed[:, top : top + h, left : left + w, :] - spatial_pos_embed = rearrange(spatial_pos_embed, "1 h w c -> 1 (h w) c") - return spatial_pos_embed - - def unpatchify(self, x, hw=None): - """ - x: (N, T, patch_size**2 * C) - imgs: (N, H, W, C) - """ - c = self.out_channels - p = self.x_embedder.patch_size[0] - if hw is None: - h = w = int(x.shape[1] ** 0.5) - else: - h, w = hw - h = h // p - w = w // p - assert h * w == x.shape[1] - - x = x.reshape(shape=(x.shape[0], h, w, p, p, c)) - x = torch.einsum("nhwpqc->nchpwq", x) - imgs = x.reshape(shape=(x.shape[0], c, h * p, w * p)) - return imgs - - def forward_core_with_concat(self, x: torch.Tensor, c_mod: torch.Tensor, context: Optional[torch.Tensor] = None) -> torch.Tensor: - if self.register_length > 0: - context = torch.cat((repeat(self.register, "1 ... -> b ...", b=x.shape[0]), context if context is not None else torch.Tensor([]).type_as(x)), 1) - - # context is B, L', D - # x is B, L, D - for block in self.joint_blocks: - context, x = block(context, x, c=c_mod) - - x = self.final_layer(x, c_mod) # (N, T, patch_size ** 2 * out_channels) - return x - - def forward(self, x: torch.Tensor, t: torch.Tensor, y: Optional[torch.Tensor] = None, context: Optional[torch.Tensor] = None) -> torch.Tensor: - """ - Forward pass of DiT. - x: (N, C, H, W) tensor of spatial inputs (images or latent representations of images) - t: (N,) tensor of diffusion timesteps - y: (N,) tensor of class labels - """ - hw = x.shape[-2:] - x = self.x_embedder(x) + self.cropped_pos_embed(hw) - c = self.t_embedder(t, dtype=x.dtype) # (N, D) - if y is not None: - y = self.y_embedder(y) # (N, D) - c = c + y # (N, D) - - context = self.context_embedder(context) - - x = self.forward_core_with_concat(x, c, context) - - x = self.unpatchify(x, hw=hw) # (N, out_channels, H, W) - return x diff --git a/demo/Diffusion/demo_diffusion/utils_sd3/other_impls.py b/demo/Diffusion/demo_diffusion/utils_sd3/other_impls.py deleted file mode 100644 index a771c1974..000000000 --- a/demo/Diffusion/demo_diffusion/utils_sd3/other_impls.py +++ /dev/null @@ -1,555 +0,0 @@ -# MIT License - -# Copyright (c) 2024 Stability AI - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import torch, math -import numpy as np -from torch import nn -from transformers import CLIPTokenizer, T5TokenizerFast - -def load_into(f, model, prefix, device, dtype=None): - """Just a debugging-friendly hack to apply the weights in a safetensors file to the pytorch module.""" - for key in f.keys(): - if key.startswith(prefix) and not key.startswith("loss."): - path = key[len(prefix):].split(".") - obj = model - for p in path: - if obj is list: - obj = obj[int(p)] - else: - obj = getattr(obj, p, None) - if obj is None: - print(f"Skipping key '{key}' in safetensors file as '{p}' does not exist in python model") - break - if obj is None: - continue - try: - tensor = f.get_tensor(key).to(device=device) - if dtype is not None: - tensor = tensor.to(dtype=dtype) - obj.requires_grad_(False) - obj.set_(tensor) - except Exception as e: - print(f"Failed to load key '{key}' in safetensors file: {e}") - raise e - -def preprocess_image_sd3(image): - image.convert("RGB") - image_np = np.array(image).astype(np.float32) / 255.0 - image_np = np.moveaxis(image_np, 2, 0) - batch_images = np.expand_dims(image_np, axis=0).repeat(1, axis=0) - image_torch = torch.from_numpy(batch_images) - image_torch = 2.0 * image_torch - 1.0 - - return image_torch - - -################################################################################################# -### Core/Utility -################################################################################################# - - -def attention(q, k, v, heads, mask=None): - """Convenience wrapper around a basic attention operation""" - b, _, dim_head = q.shape - dim_head //= heads - q, k, v = map(lambda t: t.view(b, -1, heads, dim_head).transpose(1, 2), (q, k, v)) - out = torch.nn.functional.scaled_dot_product_attention(q, k, v, attn_mask=mask, dropout_p=0.0, is_causal=False) - return out.transpose(1, 2).reshape(b, -1, heads * dim_head) - - -class Mlp(nn.Module): - """ MLP as used in Vision Transformer, MLP-Mixer and related networks""" - def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, bias=True, dtype=None, device=None): - super().__init__() - out_features = out_features or in_features - hidden_features = hidden_features or in_features - - self.fc1 = nn.Linear(in_features, hidden_features, bias=bias, dtype=dtype, device=device) - self.act = act_layer - self.fc2 = nn.Linear(hidden_features, out_features, bias=bias, dtype=dtype, device=device) - - def forward(self, x): - x = self.fc1(x) - x = self.act(x) - x = self.fc2(x) - return x - - -################################################################################################# -### CLIP -################################################################################################# - - -class CLIPAttention(torch.nn.Module): - def __init__(self, embed_dim, heads, dtype, device): - super().__init__() - self.heads = heads - self.q_proj = nn.Linear(embed_dim, embed_dim, bias=True, dtype=dtype, device=device) - self.k_proj = nn.Linear(embed_dim, embed_dim, bias=True, dtype=dtype, device=device) - self.v_proj = nn.Linear(embed_dim, embed_dim, bias=True, dtype=dtype, device=device) - self.out_proj = nn.Linear(embed_dim, embed_dim, bias=True, dtype=dtype, device=device) - - def forward(self, x, mask=None): - q = self.q_proj(x) - k = self.k_proj(x) - v = self.v_proj(x) - out = attention(q, k, v, self.heads, mask) - return self.out_proj(out) - - -ACTIVATIONS = { - "quick_gelu": lambda a: a * torch.sigmoid(1.702 * a), - "gelu": torch.nn.functional.gelu, -} - -class CLIPLayer(torch.nn.Module): - def __init__(self, embed_dim, heads, intermediate_size, intermediate_activation, dtype, device): - super().__init__() - self.layer_norm1 = nn.LayerNorm(embed_dim, dtype=dtype, device=device) - self.self_attn = CLIPAttention(embed_dim, heads, dtype, device) - self.layer_norm2 = nn.LayerNorm(embed_dim, dtype=dtype, device=device) - #self.mlp = CLIPMLP(embed_dim, intermediate_size, intermediate_activation, dtype, device) - self.mlp = Mlp(embed_dim, intermediate_size, embed_dim, act_layer=ACTIVATIONS[intermediate_activation], dtype=dtype, device=device) - - def forward(self, x, mask=None): - x += self.self_attn(self.layer_norm1(x), mask) - x += self.mlp(self.layer_norm2(x)) - return x - - -class CLIPEncoder(torch.nn.Module): - def __init__(self, num_layers, embed_dim, heads, intermediate_size, intermediate_activation, dtype, device): - super().__init__() - self.layers = torch.nn.ModuleList([CLIPLayer(embed_dim, heads, intermediate_size, intermediate_activation, dtype, device) for i in range(num_layers)]) - - def forward(self, x, mask=None, intermediate_output=None): - if intermediate_output is not None: - if intermediate_output < 0: - intermediate_output = len(self.layers) + intermediate_output - intermediate = None - for i, l in enumerate(self.layers): - x = l(x, mask) - if i == intermediate_output: - intermediate = x.clone() - return x, intermediate - - -class CLIPEmbeddings(torch.nn.Module): - def __init__(self, embed_dim, vocab_size=49408, num_positions=77, dtype=None, device=None): - super().__init__() - self.token_embedding = torch.nn.Embedding(vocab_size, embed_dim, dtype=dtype, device=device) - self.position_embedding = torch.nn.Embedding(num_positions, embed_dim, dtype=dtype, device=device) - - def forward(self, input_tokens): - return self.token_embedding(input_tokens) + self.position_embedding.weight - - -class CLIPTextModel_(torch.nn.Module): - def __init__(self, config_dict, dtype, device): - num_layers = config_dict["num_hidden_layers"] - embed_dim = config_dict["hidden_size"] - heads = config_dict["num_attention_heads"] - intermediate_size = config_dict["intermediate_size"] - intermediate_activation = config_dict["hidden_act"] - super().__init__() - self.embeddings = CLIPEmbeddings(embed_dim, dtype=dtype, device=device) - self.encoder = CLIPEncoder(num_layers, embed_dim, heads, intermediate_size, intermediate_activation, dtype, device) - self.final_layer_norm = nn.LayerNorm(embed_dim, dtype=dtype, device=device) - - def forward(self, input_tokens, intermediate_output=None, final_layer_norm_intermediate=True): - x = self.embeddings(input_tokens) - causal_mask = torch.empty(x.shape[1], x.shape[1], dtype=x.dtype, device=x.device).fill_(float("-inf")).triu_(1) - x, i = self.encoder(x, mask=causal_mask, intermediate_output=intermediate_output) - x = self.final_layer_norm(x) - if i is not None and final_layer_norm_intermediate: - i = self.final_layer_norm(i) - pooled_output = x[torch.arange(x.shape[0], device=x.device), input_tokens.to(dtype=torch.int, device=x.device).argmax(dim=-1),] - return x, i, pooled_output - - -class CLIPTextModel(torch.nn.Module): - def __init__(self, config_dict, dtype, device): - super().__init__() - self.num_layers = config_dict["num_hidden_layers"] - self.text_model = CLIPTextModel_(config_dict, dtype, device) - embed_dim = config_dict["hidden_size"] - self.text_projection = nn.Linear(embed_dim, embed_dim, bias=False, dtype=dtype, device=device) - - # WAR for RuntimeError: a leaf Variable that requires grad is being used in an in-place operation. - with torch.no_grad(): - self.text_projection.weight.copy_(torch.eye(embed_dim)) - self.dtype = dtype - - def get_input_embeddings(self): - return self.text_model.embeddings.token_embedding - - def set_input_embeddings(self, embeddings): - self.text_model.embeddings.token_embedding = embeddings - - def forward(self, *args, **kwargs): - x = self.text_model(*args, **kwargs) - out = self.text_projection(x[2]) - return (x[0], x[1], out, x[2]) - - -class SDTokenizer: - def __init__(self, max_length=77, pad_with_end=True, tokenizer=None, has_start_token=True, pad_to_max_length=True, min_length=None): - self.tokenizer = tokenizer - self.max_length = max_length - self.min_length = min_length - empty = self.tokenizer('')["input_ids"] - if has_start_token: - self.tokens_start = 1 - self.start_token = empty[0] - self.end_token = empty[1] - else: - self.tokens_start = 0 - self.start_token = None - self.end_token = empty[0] - self.pad_with_end = pad_with_end - self.pad_to_max_length = pad_to_max_length - vocab = self.tokenizer.get_vocab() - self.inv_vocab = {v: k for k, v in vocab.items()} - self.max_word_length = 8 - - - def tokenize_with_weights(self, text:str): - """Tokenize the text, with weight values - presume 1.0 for all and ignore other features here. The details aren't relevant for a reference impl, and weights themselves has weak effect on SD3.""" - if self.pad_with_end: - pad_token = self.end_token - else: - pad_token = 0 - batch = [] - if self.start_token is not None: - batch.append((self.start_token, 1.0)) - to_tokenize = text.replace("\n", " ").split(' ') - to_tokenize = [x for x in to_tokenize if x != ""] - for word in to_tokenize: - batch.extend([(t, 1) for t in self.tokenizer(word)["input_ids"][self.tokens_start:-1]]) - batch.append((self.end_token, 1.0)) - if self.pad_to_max_length: - batch.extend([(pad_token, 1.0)] * (self.max_length - len(batch))) - if self.min_length is not None and len(batch) < self.min_length: - batch.extend([(pad_token, 1.0)] * (self.min_length - len(batch))) - if len(batch) > self.max_length: - batch = batch[:self.max_length] - return [batch] - - -class SDXLClipGTokenizer(SDTokenizer): - def __init__(self, tokenizer): - super().__init__(pad_with_end=False, tokenizer=tokenizer) - - -class SD3Tokenizer: - def __init__(self): - clip_tokenizer = CLIPTokenizer.from_pretrained("openai/clip-vit-large-patch14") - self.clip_l = SDTokenizer(tokenizer=clip_tokenizer) - self.clip_g = SDXLClipGTokenizer(clip_tokenizer) - self.t5xxl = T5XXLTokenizer() - - def tokenize_with_weights(self, text:str): - out = {} - out["g"] = self.clip_g.tokenize_with_weights(text) - out["l"] = self.clip_l.tokenize_with_weights(text) - out["t5xxl"] = self.t5xxl.tokenize_with_weights(text) - return out - -class ClipTokenWeightEncoder: - def encode_token_weights(self, token_weight_pairs): - tokens = list(map(lambda a: a[0], token_weight_pairs[0])) - - # model inference - tokens = torch.tensor([tokens], dtype=torch.int64, device="cuda") - out, pooled = self(tokens) - - if pooled is not None: - first_pooled = pooled[0:1].cuda() - else: - first_pooled = pooled - output = [out[0:1]] - - return torch.cat(output, dim=-2).cuda(), first_pooled - -class SDClipModel(torch.nn.Module, ClipTokenWeightEncoder): - """Uses the CLIP transformer encoder for text (from huggingface)""" - LAYERS = ["last", "pooled", "hidden"] - def __init__(self, device="cuda", max_length=77, layer="last", layer_idx=None, textmodel_json_config=None, dtype=None, model_class=CLIPTextModel, - special_tokens={"start": 49406, "end": 49407, "pad": 49407}, layer_norm_hidden_state=True, return_projected_pooled=True): - super().__init__() - assert layer in self.LAYERS - self.transformer = model_class(textmodel_json_config, dtype, device) - self.num_layers = self.transformer.num_layers - self.max_length = max_length - self.transformer = self.transformer.eval() - for param in self.parameters(): - param.requires_grad = False - self.layer = layer - self.layer_idx = None - self.special_tokens = special_tokens - self.logit_scale = torch.nn.Parameter(torch.tensor(4.6055)) - self.layer_norm_hidden_state = layer_norm_hidden_state - self.return_projected_pooled = return_projected_pooled - if layer == "hidden": - assert layer_idx is not None - assert abs(layer_idx) < self.num_layers - self.set_clip_options({"layer": layer_idx}) - self.options_default = (self.layer, self.layer_idx, self.return_projected_pooled) - - def set_clip_options(self, options): - layer_idx = options.get("layer", self.layer_idx) - self.return_projected_pooled = options.get("projected_pooled", self.return_projected_pooled) - if layer_idx is None or abs(layer_idx) > self.num_layers: - self.layer = "last" - else: - self.layer = "hidden" - self.layer_idx = layer_idx - - def forward(self, tokens): - backup_embeds = self.transformer.get_input_embeddings() - outputs = self.transformer(tokens, intermediate_output=self.layer_idx, final_layer_norm_intermediate=self.layer_norm_hidden_state) - self.transformer.set_input_embeddings(backup_embeds) - if self.layer == "last": - z = outputs[0] - else: - z = outputs[1] - pooled_output = None - if len(outputs) >= 3: - if not self.return_projected_pooled and len(outputs) >= 4 and outputs[3] is not None: - pooled_output = outputs[3].float() - elif outputs[2] is not None: - pooled_output = outputs[2].float() - return z.float(), pooled_output - - -class SDXLClipG(SDClipModel): - """Wraps the CLIP-G model into the SD-CLIP-Model interface""" - def __init__(self, config, device="cuda", layer="penultimate", layer_idx=None, dtype=None): - if layer == "penultimate": - layer="hidden" - layer_idx=-2 - super().__init__(device=device, layer=layer, layer_idx=layer_idx, textmodel_json_config=config, dtype=dtype, special_tokens={"start": 49406, "end": 49407, "pad": 0}, layer_norm_hidden_state=False) - - -class T5XXLModel(SDClipModel): - """Wraps the T5-XXL model into the SD-CLIP-Model interface for convenience""" - def __init__(self, config, device="cuda", layer="last", layer_idx=None, dtype=None): - super().__init__(device=device, layer=layer, layer_idx=layer_idx, textmodel_json_config=config, dtype=dtype, special_tokens={"end": 1, "pad": 0}, model_class=T5) - - -################################################################################################# -### T5 implementation, for the T5-XXL text encoder portion, largely pulled from upstream impl -################################################################################################# - - -class T5XXLTokenizer(SDTokenizer): - """Wraps the T5 Tokenizer from HF into the SDTokenizer interface""" - def __init__(self): - super().__init__(pad_with_end=False, tokenizer=T5TokenizerFast.from_pretrained("google/t5-v1_1-xxl"), has_start_token=False, pad_to_max_length=False, max_length=99999999, min_length=77) - - -class T5LayerNorm(torch.nn.Module): - def __init__(self, hidden_size, eps=1e-6, dtype=None, device=None): - super().__init__() - self.weight = torch.nn.Parameter(torch.ones(hidden_size, dtype=dtype, device=device)) - self.variance_epsilon = eps - - def forward(self, x): - variance = x.pow(2).mean(-1, keepdim=True) - x = x * torch.rsqrt(variance + self.variance_epsilon) - return self.weight.to(device=x.device, dtype=x.dtype) * x - - -class T5DenseGatedActDense(torch.nn.Module): - def __init__(self, model_dim, ff_dim, dtype, device): - super().__init__() - self.wi_0 = nn.Linear(model_dim, ff_dim, bias=False, dtype=dtype, device=device) - self.wi_1 = nn.Linear(model_dim, ff_dim, bias=False, dtype=dtype, device=device) - self.wo = nn.Linear(ff_dim, model_dim, bias=False, dtype=dtype, device=device) - - def forward(self, x): - hidden_gelu = torch.nn.functional.gelu(self.wi_0(x), approximate="tanh") - hidden_linear = self.wi_1(x) - x = hidden_gelu * hidden_linear - x = self.wo(x) - return x - - -class T5LayerFF(torch.nn.Module): - def __init__(self, model_dim, ff_dim, dtype, device): - super().__init__() - self.DenseReluDense = T5DenseGatedActDense(model_dim, ff_dim, dtype, device) - self.layer_norm = T5LayerNorm(model_dim, dtype=dtype, device=device) - - def forward(self, x): - forwarded_states = self.layer_norm(x) - forwarded_states = self.DenseReluDense(forwarded_states) - x += forwarded_states - return x - - -class T5Attention(torch.nn.Module): - def __init__(self, model_dim, inner_dim, num_heads, relative_attention_bias, dtype, device): - super().__init__() - # Mesh TensorFlow initialization to avoid scaling before softmax - self.q = nn.Linear(model_dim, inner_dim, bias=False, dtype=dtype, device=device) - self.k = nn.Linear(model_dim, inner_dim, bias=False, dtype=dtype, device=device) - self.v = nn.Linear(model_dim, inner_dim, bias=False, dtype=dtype, device=device) - self.o = nn.Linear(inner_dim, model_dim, bias=False, dtype=dtype, device=device) - self.num_heads = num_heads - self.relative_attention_bias = None - if relative_attention_bias: - self.relative_attention_num_buckets = 32 - self.relative_attention_max_distance = 128 - self.relative_attention_bias = torch.nn.Embedding(self.relative_attention_num_buckets, self.num_heads, device=device, dtype=dtype) - - @staticmethod - def _relative_position_bucket(relative_position, bidirectional=True, num_buckets=32, max_distance=128): - """ - Adapted from Mesh Tensorflow: - https://github.com/tensorflow/mesh/blob/0cb87fe07da627bf0b7e60475d59f95ed6b5be3d/mesh_tensorflow/transformer/transformer_layers.py#L593 - - Translate relative position to a bucket number for relative attention. The relative position is defined as - memory_position - query_position, i.e. the distance in tokens from the attending position to the attended-to - position. If bidirectional=False, then positive relative positions are invalid. We use smaller buckets for - small absolute relative_position and larger buckets for larger absolute relative_positions. All relative - positions >=max_distance map to the same bucket. All relative positions <=-max_distance map to the same bucket. - This should allow for more graceful generalization to longer sequences than the model has been trained on - - Args: - relative_position: an int32 Tensor - bidirectional: a boolean - whether the attention is bidirectional - num_buckets: an integer - max_distance: an integer - - Returns: - a Tensor with the same shape as relative_position, containing int32 values in the range [0, num_buckets) - """ - relative_buckets = 0 - if bidirectional: - num_buckets //= 2 - relative_buckets += (relative_position > 0).to(torch.long) * num_buckets - relative_position = torch.abs(relative_position) - else: - relative_position = -torch.min(relative_position, torch.zeros_like(relative_position)) - # now relative_position is in the range [0, inf) - # half of the buckets are for exact increments in positions - max_exact = num_buckets // 2 - is_small = relative_position < max_exact - # The other half of the buckets are for logarithmically bigger bins in positions up to max_distance - relative_position_if_large = max_exact + ( - torch.log(relative_position.float() / max_exact) - / math.log(max_distance / max_exact) - * (num_buckets - max_exact) - ).to(torch.long) - relative_position_if_large = torch.min(relative_position_if_large, torch.full_like(relative_position_if_large, num_buckets - 1)) - relative_buckets += torch.where(is_small, relative_position, relative_position_if_large) - return relative_buckets - - def compute_bias(self, query_length, key_length, device): - """Compute binned relative position bias""" - context_position = torch.arange(query_length, dtype=torch.long, device=device)[:, None] - memory_position = torch.arange(key_length, dtype=torch.long, device=device)[None, :] - relative_position = memory_position - context_position # shape (query_length, key_length) - relative_position_bucket = self._relative_position_bucket( - relative_position, # shape (query_length, key_length) - bidirectional=True, - num_buckets=self.relative_attention_num_buckets, - max_distance=self.relative_attention_max_distance, - ) - values = self.relative_attention_bias(relative_position_bucket) # shape (query_length, key_length, num_heads) - values = values.permute([2, 0, 1]).unsqueeze(0) # shape (1, num_heads, query_length, key_length) - return values - - def forward(self, x, past_bias=None): - q = self.q(x) - k = self.k(x) - v = self.v(x) - if self.relative_attention_bias is not None: - past_bias = self.compute_bias(x.shape[1], x.shape[1], x.device) - if past_bias is not None: - mask = past_bias - out = attention(q, k * ((k.shape[-1] / self.num_heads) ** 0.5), v, self.num_heads, mask) - return self.o(out), past_bias - - -class T5LayerSelfAttention(torch.nn.Module): - def __init__(self, model_dim, inner_dim, ff_dim, num_heads, relative_attention_bias, dtype, device): - super().__init__() - self.SelfAttention = T5Attention(model_dim, inner_dim, num_heads, relative_attention_bias, dtype, device) - self.layer_norm = T5LayerNorm(model_dim, dtype=dtype, device=device) - - def forward(self, x, past_bias=None): - output, past_bias = self.SelfAttention(self.layer_norm(x), past_bias=past_bias) - x += output - return x, past_bias - - -class T5Block(torch.nn.Module): - def __init__(self, model_dim, inner_dim, ff_dim, num_heads, relative_attention_bias, dtype, device): - super().__init__() - self.layer = torch.nn.ModuleList() - self.layer.append(T5LayerSelfAttention(model_dim, inner_dim, ff_dim, num_heads, relative_attention_bias, dtype, device)) - self.layer.append(T5LayerFF(model_dim, ff_dim, dtype, device)) - - def forward(self, x, past_bias=None): - x, past_bias = self.layer[0](x, past_bias) - x = self.layer[-1](x) - return x, past_bias - - -class T5Stack(torch.nn.Module): - def __init__(self, num_layers, model_dim, inner_dim, ff_dim, num_heads, vocab_size, dtype, device): - super().__init__() - self.embed_tokens = torch.nn.Embedding(vocab_size, model_dim, device=device, dtype=dtype) - self.block = torch.nn.ModuleList([T5Block(model_dim, inner_dim, ff_dim, num_heads, relative_attention_bias=(i == 0), dtype=dtype, device=device) for i in range(num_layers)]) - self.final_layer_norm = T5LayerNorm(model_dim, dtype=dtype, device=device) - - def forward(self, input_ids, intermediate_output=None, final_layer_norm_intermediate=True): - intermediate = None - x = self.embed_tokens(input_ids) - past_bias = None - for i, l in enumerate(self.block): - x, past_bias = l(x, past_bias) - if i == intermediate_output: - intermediate = x.clone() - x = self.final_layer_norm(x) - if intermediate is not None and final_layer_norm_intermediate: - intermediate = self.final_layer_norm(intermediate) - return x, intermediate - - -class T5(torch.nn.Module): - def __init__(self, config_dict, dtype, device): - super().__init__() - self.num_layers = config_dict["num_layers"] - self.encoder = T5Stack(self.num_layers, config_dict["d_model"], config_dict["d_model"], config_dict["d_ff"], config_dict["num_heads"], config_dict["vocab_size"], dtype, device) - self.dtype = dtype - - def get_input_embeddings(self): - return self.encoder.embed_tokens - - def set_input_embeddings(self, embeddings): - self.encoder.embed_tokens = embeddings - - def forward(self, *args, **kwargs): - return self.encoder(*args, **kwargs) diff --git a/demo/Diffusion/demo_diffusion/utils_sd3/sd3_impls.py b/demo/Diffusion/demo_diffusion/utils_sd3/sd3_impls.py deleted file mode 100644 index 6385c1e07..000000000 --- a/demo/Diffusion/demo_diffusion/utils_sd3/sd3_impls.py +++ /dev/null @@ -1,391 +0,0 @@ -# MIT License - -# Copyright (c) 2024 Stability AI - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import math - -import einops -import torch -from PIL import Image - -from demo_diffusion.utils_sd3.mmdit import MMDiT - -################################################################################################# -### MMDiT Model Wrapping -################################################################################################# - - -class ModelSamplingDiscreteFlow(torch.nn.Module): - """Helper for sampler scheduling (ie timestep/sigma calculations) for Discrete Flow models""" - def __init__(self, shift=1.0): - super().__init__() - self.shift = shift - timesteps = 1000 - ts = self.sigma(torch.arange(1, timesteps + 1, 1)) - self.register_buffer('sigmas', ts) - - @property - def sigma_min(self): - return self.sigmas[0] - - @property - def sigma_max(self): - return self.sigmas[-1] - - def timestep(self, sigma): - return sigma * 1000 - - def sigma(self, timestep: torch.Tensor): - timestep = timestep / 1000.0 - if self.shift == 1.0: - return timestep - return self.shift * timestep / (1 + (self.shift - 1) * timestep) - - def calculate_denoised(self, sigma, model_output, model_input): - sigma = sigma.view(sigma.shape[:1] + (1,) * (model_output.ndim - 1)) - return model_input - model_output * sigma - - def noise_scaling(self, sigma, noise, latent_image, max_denoise=False): - return sigma * noise + (1.0 - sigma) * latent_image - - -class BaseModel(torch.nn.Module): - """Wrapper around the core MM-DiT model""" - def __init__(self, shift=1.0, device=None, dtype=torch.float32, file=None, prefix=""): - super().__init__() - # Important configuration values can be quickly determined by checking shapes in the source file - # Some of these will vary between models (eg 2B vs 8B primarily differ in their depth, but also other details change) - patch_size = file.get_tensor(f"{prefix}x_embedder.proj.weight").shape[2] - depth = file.get_tensor(f"{prefix}x_embedder.proj.weight").shape[0] // 64 - num_patches = file.get_tensor(f"{prefix}pos_embed").shape[1] - pos_embed_max_size = round(math.sqrt(num_patches)) - adm_in_channels = file.get_tensor(f"{prefix}y_embedder.mlp.0.weight").shape[1] - context_shape = file.get_tensor(f"{prefix}context_embedder.weight").shape - context_embedder_config = { - "target": "torch.nn.Linear", - "params": { - "in_features": context_shape[1], - "out_features": context_shape[0] - } - } - self.diffusion_model = MMDiT(input_size=None, pos_embed_scaling_factor=None, pos_embed_offset=None, pos_embed_max_size=pos_embed_max_size, patch_size=patch_size, in_channels=16, depth=depth, num_patches=num_patches, adm_in_channels=adm_in_channels, context_embedder_config=context_embedder_config, device=device, dtype=dtype) - self.model_sampling = ModelSamplingDiscreteFlow(shift=shift) - - def forward(self, x, sigma, c_crossattn=None, y=None): - dtype = self.get_dtype() - timestep = self.model_sampling.timestep(sigma).float() - model_output = self.diffusion_model(x.to(dtype), timestep, context=c_crossattn.to(dtype), y=y.to(dtype)).float() - return self.model_sampling.calculate_denoised(sigma, model_output, x) - - def get_dtype(self): - return self.diffusion_model.dtype - - -class CFGDenoiser(torch.nn.Module): - """Helper for applying CFG Scaling to diffusion outputs""" - def __init__(self, model): - super().__init__() - self.model = model - - def forward(self, x, timestep, cond, uncond, cond_scale): - # Run cond and uncond in a batch together - batched = self.model(torch.cat([x, x]), torch.cat([timestep, timestep]), c_crossattn=torch.cat([cond["c_crossattn"], uncond["c_crossattn"]]), y=torch.cat([cond["y"], uncond["y"]])) - # Then split and apply CFG Scaling - pos_out, neg_out = batched.chunk(2) - scaled = neg_out + (pos_out - neg_out) * cond_scale - return scaled - - -class SD3LatentFormat: - """Latents are slightly shifted from center - this class must be called after VAE Decode to correct for the shift""" - def __init__(self): - self.scale_factor = 1.5305 - self.shift_factor = 0.0609 - - def process_in(self, latent): - return (latent - self.shift_factor) * self.scale_factor - - def process_out(self, latent): - return (latent / self.scale_factor) + self.shift_factor - - def decode_latent_to_preview(self, x0): - """Quick RGB approximate preview of sd3 latents""" - factors = torch.tensor([ - [-0.0645, 0.0177, 0.1052], [ 0.0028, 0.0312, 0.0650], - [ 0.1848, 0.0762, 0.0360], [ 0.0944, 0.0360, 0.0889], - [ 0.0897, 0.0506, -0.0364], [-0.0020, 0.1203, 0.0284], - [ 0.0855, 0.0118, 0.0283], [-0.0539, 0.0658, 0.1047], - [-0.0057, 0.0116, 0.0700], [-0.0412, 0.0281, -0.0039], - [ 0.1106, 0.1171, 0.1220], [-0.0248, 0.0682, -0.0481], - [ 0.0815, 0.0846, 0.1207], [-0.0120, -0.0055, -0.0867], - [-0.0749, -0.0634, -0.0456], [-0.1418, -0.1457, -0.1259] - ], device="cuda") - latent_image = x0[0].permute(1, 2, 0).cuda() @ factors - - latents_ubyte = (((latent_image + 1) / 2) - .clamp(0, 1) # change scale from -1..1 to 0..1 - .mul(0xFF) # to 0..255 - .byte()).cuda() - - return Image.fromarray(latents_ubyte.numpy()) - - -################################################################################################# -### K-Diffusion Sampling -################################################################################################# - - -def append_dims(x, target_dims): - """Appends dimensions to the end of a tensor until it has target_dims dimensions.""" - dims_to_append = target_dims - x.ndim - return x[(...,) + (None,) * dims_to_append] - - -def to_d(x, sigma, denoised): - """Converts a denoiser output to a Karras ODE derivative.""" - return (x - denoised) / append_dims(sigma, x.ndim) - - -@torch.no_grad() -@torch.autocast("cuda", dtype=torch.float16) -def sample_euler(func, x, sigmas, extra_args=None): - """Implements Algorithm 2 (Euler steps) from Karras et al. (2022).""" - extra_args = {} if extra_args is None else extra_args - s_in = x.new_ones([x.shape[0]]) - for i in range(len(sigmas) - 1): - sigma_hat = sigmas[i] - denoised = func(x, sigma_hat * s_in, **extra_args) - d = to_d(x, sigma_hat, denoised) - dt = sigmas[i + 1] - sigma_hat - # Euler method - x = x + d * dt - return x - - -################################################################################################# -### VAE -################################################################################################# - - -def Normalize(in_channels, num_groups=32, dtype=torch.float32, device=None): - return torch.nn.GroupNorm(num_groups=num_groups, num_channels=in_channels, eps=1e-6, affine=True, dtype=dtype, device=device) - - -class ResnetBlock(torch.nn.Module): - def __init__(self, *, in_channels, out_channels=None, dtype=torch.float32, device=None): - super().__init__() - self.in_channels = in_channels - out_channels = in_channels if out_channels is None else out_channels - self.out_channels = out_channels - - self.norm1 = Normalize(in_channels, dtype=dtype, device=device) - self.conv1 = torch.nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1, dtype=dtype, device=device) - self.norm2 = Normalize(out_channels, dtype=dtype, device=device) - self.conv2 = torch.nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, dtype=dtype, device=device) - if self.in_channels != self.out_channels: - self.nin_shortcut = torch.nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, padding=0, dtype=dtype, device=device) - else: - self.nin_shortcut = None - self.swish = torch.nn.SiLU(inplace=True) - - def forward(self, x): - hidden = x - hidden = self.norm1(hidden) - hidden = self.swish(hidden) - hidden = self.conv1(hidden) - hidden = self.norm2(hidden) - hidden = self.swish(hidden) - hidden = self.conv2(hidden) - if self.in_channels != self.out_channels: - x = self.nin_shortcut(x) - return x + hidden - - -class AttnBlock(torch.nn.Module): - def __init__(self, in_channels, dtype=torch.float32, device=None): - super().__init__() - self.norm = Normalize(in_channels, dtype=dtype, device=device) - self.q = torch.nn.Conv2d(in_channels, in_channels, kernel_size=1, stride=1, padding=0, dtype=dtype, device=device) - self.k = torch.nn.Conv2d(in_channels, in_channels, kernel_size=1, stride=1, padding=0, dtype=dtype, device=device) - self.v = torch.nn.Conv2d(in_channels, in_channels, kernel_size=1, stride=1, padding=0, dtype=dtype, device=device) - self.proj_out = torch.nn.Conv2d(in_channels, in_channels, kernel_size=1, stride=1, padding=0, dtype=dtype, device=device) - - def forward(self, x): - hidden = self.norm(x) - q = self.q(hidden) - k = self.k(hidden) - v = self.v(hidden) - b, c, h, w = q.shape - q, k, v = map(lambda x: einops.rearrange(x, "b c h w -> b 1 (h w) c").contiguous(), (q, k, v)) - hidden = torch.nn.functional.scaled_dot_product_attention(q, k, v) # scale is dim ** -0.5 per default - hidden = einops.rearrange(hidden, "b 1 (h w) c -> b c h w", h=h, w=w, c=c, b=b) - hidden = self.proj_out(hidden) - return x + hidden - - -class Downsample(torch.nn.Module): - def __init__(self, in_channels, dtype=torch.float32, device=None): - super().__init__() - self.conv = torch.nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=2, padding=0, dtype=dtype, device=device) - - def forward(self, x): - pad = (0,1,0,1) - x = torch.nn.functional.pad(x, pad, mode="constant", value=0) - x = self.conv(x) - return x - - -class Upsample(torch.nn.Module): - def __init__(self, in_channels, dtype=torch.float32, device=None): - super().__init__() - self.conv = torch.nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=1, padding=1, dtype=dtype, device=device) - - def forward(self, x): - x = torch.nn.functional.interpolate(x, scale_factor=2.0, mode="nearest") - x = self.conv(x) - return x - - -class VAEEncoder(torch.nn.Module): - def __init__(self, ch=128, ch_mult=(1,2,4,4), num_res_blocks=2, in_channels=3, z_channels=16, dtype=torch.float32, device=None): - super().__init__() - self.num_resolutions = len(ch_mult) - self.num_res_blocks = num_res_blocks - # downsampling - self.conv_in = torch.nn.Conv2d(in_channels, ch, kernel_size=3, stride=1, padding=1, dtype=dtype, device=device) - in_ch_mult = (1,) + tuple(ch_mult) - self.in_ch_mult = in_ch_mult - self.down = torch.nn.ModuleList() - for i_level in range(self.num_resolutions): - block = torch.nn.ModuleList() - attn = torch.nn.ModuleList() - block_in = ch*in_ch_mult[i_level] - block_out = ch*ch_mult[i_level] - for i_block in range(num_res_blocks): - block.append(ResnetBlock(in_channels=block_in, out_channels=block_out, dtype=dtype, device=device)) - block_in = block_out - down = torch.nn.Module() - down.block = block - down.attn = attn - if i_level != self.num_resolutions - 1: - down.downsample = Downsample(block_in, dtype=dtype, device=device) - self.down.append(down) - # middle - self.mid = torch.nn.Module() - self.mid.block_1 = ResnetBlock(in_channels=block_in, out_channels=block_in, dtype=dtype, device=device) - self.mid.attn_1 = AttnBlock(block_in, dtype=dtype, device=device) - self.mid.block_2 = ResnetBlock(in_channels=block_in, out_channels=block_in, dtype=dtype, device=device) - # end - self.norm_out = Normalize(block_in, dtype=dtype, device=device) - self.conv_out = torch.nn.Conv2d(block_in, 2 * z_channels, kernel_size=3, stride=1, padding=1, dtype=dtype, device=device) - self.swish = torch.nn.SiLU(inplace=True) - - def forward(self, x): - # downsampling - hs = [self.conv_in(x)] - for i_level in range(self.num_resolutions): - for i_block in range(self.num_res_blocks): - h = self.down[i_level].block[i_block](hs[-1]) - hs.append(h) - if i_level != self.num_resolutions-1: - hs.append(self.down[i_level].downsample(hs[-1])) - # middle - h = hs[-1] - h = self.mid.block_1(h) - h = self.mid.attn_1(h) - h = self.mid.block_2(h) - # end - h = self.norm_out(h) - h = self.swish(h) - h = self.conv_out(h) - return h - - -class VAEDecoder(torch.nn.Module): - def __init__(self, ch=128, out_ch=3, ch_mult=(1, 2, 4, 4), num_res_blocks=2, resolution=256, z_channels=16, dtype=torch.float32, device=None): - super().__init__() - self.num_resolutions = len(ch_mult) - self.num_res_blocks = num_res_blocks - block_in = ch * ch_mult[self.num_resolutions - 1] - curr_res = resolution // 2 ** (self.num_resolutions - 1) - # z to block_in - self.conv_in = torch.nn.Conv2d(z_channels, block_in, kernel_size=3, stride=1, padding=1, dtype=dtype, device=device) - # middle - self.mid = torch.nn.Module() - self.mid.block_1 = ResnetBlock(in_channels=block_in, out_channels=block_in, dtype=dtype, device=device) - self.mid.attn_1 = AttnBlock(block_in, dtype=dtype, device=device) - self.mid.block_2 = ResnetBlock(in_channels=block_in, out_channels=block_in, dtype=dtype, device=device) - # upsampling - self.up = torch.nn.ModuleList() - for i_level in reversed(range(self.num_resolutions)): - block = torch.nn.ModuleList() - block_out = ch * ch_mult[i_level] - for i_block in range(self.num_res_blocks + 1): - block.append(ResnetBlock(in_channels=block_in, out_channels=block_out, dtype=dtype, device=device)) - block_in = block_out - up = torch.nn.Module() - up.block = block - if i_level != 0: - up.upsample = Upsample(block_in, dtype=dtype, device=device) - curr_res = curr_res * 2 - self.up.insert(0, up) # prepend to get consistent order - # end - self.norm_out = Normalize(block_in, dtype=dtype, device=device) - self.conv_out = torch.nn.Conv2d(block_in, out_ch, kernel_size=3, stride=1, padding=1, dtype=dtype, device=device) - self.swish = torch.nn.SiLU(inplace=True) - - def forward(self, z): - # z to block_in - hidden = self.conv_in(z) - # middle - hidden = self.mid.block_1(hidden) - hidden = self.mid.attn_1(hidden) - hidden = self.mid.block_2(hidden) - # upsampling - for i_level in reversed(range(self.num_resolutions)): - for i_block in range(self.num_res_blocks + 1): - hidden = self.up[i_level].block[i_block](hidden) - if i_level != 0: - hidden = self.up[i_level].upsample(hidden) - # end - hidden = self.norm_out(hidden) - hidden = self.swish(hidden) - hidden = self.conv_out(hidden) - return hidden - - -class SDVAE(torch.nn.Module): - def __init__(self, dtype=torch.float32, device=None): - super().__init__() - self.encoder = VAEEncoder(dtype=dtype, device=device) - self.decoder = VAEDecoder(dtype=dtype, device=device) - - @torch.autocast("cuda", dtype=torch.float16) - def decode(self, latent): - return self.decoder(latent) - - @torch.autocast("cuda", dtype=torch.float16) - def encode(self, image): - hidden = self.encoder(image) - mean, logvar = torch.chunk(hidden, 2, dim=1) - logvar = torch.clamp(logvar, -30.0, 20.0) - std = torch.exp(0.5 * logvar) - return mean + std * torch.randn_like(mean) diff --git a/demo/Diffusion/demo_img2img.py b/demo/Diffusion/demo_img2img.py deleted file mode 100644 index 176471fb5..000000000 --- a/demo/Diffusion/demo_img2img.py +++ /dev/null @@ -1,81 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("sd") - -import argparse - -import PIL -from cuda.bindings import runtime as cudart -from PIL import Image - -from demo_diffusion import dd_argparse -from demo_diffusion import image as image_module -from demo_diffusion import pipeline as pipeline_module - - -def parseArgs(): - parser = argparse.ArgumentParser(description="Options for Stable Diffusion Img2Img Demo") - parser = dd_argparse.add_arguments(parser) - parser.add_argument('--input-image', type=str, default="", help="Path to the input image") - return parser.parse_args() - -if __name__ == "__main__": - print("[I] Initializing StableDiffusion img2img demo using TensorRT") - args = parseArgs() - - if args.input_image: - input_image = Image.open(args.input_image) - else: - url = "https://raw.githubusercontent.com/CompVis/stable-diffusion/main/assets/stable-samples/img2img/sketch-mountains-input.jpg" - input_image = image_module.download_image(url) - - image_width, image_height = input_image.size - if image_height != args.height or image_width != args.width: - print(f"[I] Resizing input_image to {args.height}x{args.width}") - input_image = input_image.resize((args.width, args.height)) - image_height, image_width = args.height, args.width - - if isinstance(input_image, PIL.Image.Image): - input_image = image_module.preprocess_image(input_image) - - kwargs_init_pipeline, kwargs_load_engine, args_run_demo = dd_argparse.process_pipeline_args(args) - - # Initialize demo - demo = pipeline_module.StableDiffusionPipeline( - pipeline_type=pipeline_module.PIPELINE_TYPE.IMG2IMG, **kwargs_init_pipeline - ) - - # Load TensorRT engines and pytorch modules - demo.loadEngines( - args.engine_dir, - args.framework_model_dir, - args.onnx_dir, - **kwargs_load_engine) - - # Load resources - _, shared_device_memory = cudart.cudaMalloc(demo.calculateMaxDeviceMemory()) - demo.activateEngines(shared_device_memory) - demo.loadResources(args.height, args.width, args.batch_size, args.seed) - - # Run inference - demo_kwargs = {'input_image': input_image, 'image_strength': 0.75} - demo.run(*args_run_demo, **demo_kwargs) - - demo.teardown() diff --git a/demo/Diffusion/demo_img2img_flux.py b/demo/Diffusion/demo_img2img_flux.py deleted file mode 100755 index 5c46cf101..000000000 --- a/demo/Diffusion/demo_img2img_flux.py +++ /dev/null @@ -1,284 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("flux") - -import argparse -import os - -import controlnet_aux -from cuda.bindings import runtime as cudart -from PIL import Image - -from demo_diffusion import dd_argparse -from demo_diffusion import pipeline as pipeline_module - - -def parse_args(): - parser = argparse.ArgumentParser(description="Options for Flux Img2Img Demo", conflict_handler="resolve") - parser = dd_argparse.add_arguments(parser) - parser.add_argument( - "--version", - type=str, - default="flux.1-dev", - choices=("flux.1-dev", "flux.1-schnell", "flux.1-dev-canny", "flux.1-dev-depth", "flux.1-kontext-dev"), - help="Version of Flux", - ) - parser.add_argument( - "--prompt2", - default=None, - nargs="*", - help="Text prompt(s) to be sent to the T5 tokenizer and text encoder. If not defined, prompt will be used instead", - ) - parser.add_argument( - "--height", - type=int, - default=1024, - help="Height of image to generate (must be multiple of 8)", - ) - parser.add_argument( - "--width", - type=int, - default=1024, - help="Width of image to generate (must be multiple of 8)", - ) - parser.add_argument("--denoising-steps", type=int, default=50, help="Number of denoising steps") - parser.add_argument( - "--guidance-scale", - type=float, - default=3.5, - help="Value of classifier-free guidance scale (must be greater than 1)", - ) - parser.add_argument( - "--max_sequence_length", - type=int, - help="Maximum sequence length to use with the prompt. Can be up to 512 for the dev and 256 for the schnell variant.", - ) - parser.add_argument( - "--t5-ws-percentage", - type=int, - default=None, - help="Set runtime weight streaming budget as the percentage of the size of streamable weights for the T5 model. This argument only takes effect when --ws is set. 0 streams the most weights and 100 or None streams no weights. ", - ) - - parser.add_argument( - "--transformer-ws-percentage", - type=int, - default=None, - help="Set runtime weight streaming budget as the percentage of the size of streamable weights for the transformer model. This argument only takes effect when --ws is set. 0 streams the most weights and 100 or None streams no weights.", - ) - parser.add_argument( - "--control-image", - type=str, - default=None, - help="Path to the control image for the flux.1-dev-canny and flux.1-dev-depth pipelines", - ) - parser.add_argument( - "--input-image", - type=str, - default=None, - help="Path to the input conditioning image for the flux.1-dev and flux.1-schnell img2img pipelines", - ) - parser.add_argument( - "--kontext-image", - type=str, - default=None, - help="Path to the input image for Kontext pipeline (flux.1-kontext-dev only, required)", - ) - parser.add_argument( - "--image-strength", - type=float, - default=1.0, - help="Indicates extent to transform the reference `image`. Must be between 0 and 1. A value of 1 essentially ignores the input image.", - ) - parser.add_argument( - "--calibration-dataset", - type=str, - default=None, - help="Path to the calibration dataset for quantization (only enabled for controlnet)", - ) - - return parser.parse_args() - - -def process_demo_args(args): - batch_size = args.batch_size - prompt = args.prompt - # If prompt2 is not defined, use prompt instead - prompt2 = args.prompt2 or prompt - - # Process input args - if not isinstance(prompt, list): - raise ValueError(f"`prompt` must be of type `list[str]`, but is {type(prompt)}") - prompt = prompt * batch_size - - if not isinstance(prompt2, list): - raise ValueError(f"`prompt2` must be of type `str` list, but is {type(prompt2)}") - if len(prompt2) == 1: - prompt2 = prompt2 * batch_size - - max_seq_supported_by_model = { - "flux.1-schnell": 256, - "flux.1-dev": 512, - "flux.1-dev-canny": 512, - "flux.1-dev-depth": 512, - "flux.1-kontext-dev": 512, - }[args.version] - if args.max_sequence_length is not None: - if args.max_sequence_length > max_seq_supported_by_model: - raise ValueError( - f"For {args.version}, `max_sequence_length` cannot be greater than {max_seq_supported_by_model} but is {args.max_sequence_length}" - ) - else: - args.max_sequence_length = max_seq_supported_by_model - - controlnet_type = "depth" if "depth" in args.version else "canny" if "canny" in args.version else "" - if controlnet_type: - if args.input_image: - raise ValueError( - f"--input-image is a valid input for versions [flux.1-dev, flux.1-schnell]. Provided {args.version}" - ) - if not args.control_image: - raise ValueError( - "--control-image input is required for versions [flux.1-dev-canny, flux.1-dev-depth]. Please provide it using --control-image flag." - ) - args.control_image = Image.open(args.control_image).convert("RGB") - - if controlnet_type == "canny": - processor = controlnet_aux.CannyDetector() - args.control_image = processor( - args.control_image, low_threshold=50, high_threshold=200, detect_resolution=1024, image_resolution=1024 - ) - elif controlnet_type == "depth": - args.control_image = controlnet_aux.LeresDetector.from_pretrained("lllyasviel/Annotators")( - args.control_image - ) - else: - raise ValueError("Invalid controlnet type") - else: - if args.control_image: - raise ValueError( - f"--control-image is a valid input for versions [flux.1-dev-canny, flux.1-dev-depth]. Provided {args.version}" - ) - - # Handle input image for img2img pipelines - if args.version == "flux.1-kontext-dev": - # For Kontext pipeline, only use kontext-image - if not args.kontext_image: - raise ValueError( - "--kontext-image is required for the Kontext pipeline. Please provide it using the --kontext-image flag." - ) - if args.input_image: - raise ValueError( - "--input-image is not supported for the Kontext pipeline. Please use --kontext-image instead." - ) - # Kontext pipeline doesn't resize the input image - args.kontext_image = Image.open(args.kontext_image).convert("RGB") - else: - if not args.input_image: - raise ValueError( - "--input-image is required for the img2img pipeline. Please provide it using the --input-image flag." - ) - args.input_image = Image.open(args.input_image).convert("RGB").resize((args.width, args.height)) - - if args.fp8: - if args.version == "flux.1-dev" or args.version == "flux.1-schnell": - raise ValueError("--fp8 is currently not supported for Flux.1-dev and Flux.1-schnell img2img pipelines.") - - if not args.calibration_dataset: - args.calibration_dataset = os.path.join(f"{controlnet_type}-eval", "benchmark") - print(f"[W] Calibration dataset path not provided, setting default path to {args.calibration_dataset}.") - - if not os.path.exists(args.calibration_dataset): - print( - f"[W] Could not find the calibration dataset at {args.calibration_dataset}, and will fallback to using pre-exported ONNX models. Please follow the instructions in README to download calibration dataset and provide the path if pre-exported ONNX models are not provided either." - ) - - if args.version == "flux.1-kontext-dev" and not args.download_onnx_models: - raise ValueError( - "--download-onnx-models is required when using --fp8 for Flux.1-kontext-dev img2img pipeline." - ) - - if args.fp4: - if args.version == "flux.1-dev" or args.version == "flux.1-schnell": - raise ValueError("--fp4 is currently not supported for Flux.1-dev and Flux.1-schnell img2img pipelines.") - if not args.download_onnx_models: - raise ValueError("--download-onnx-models is required when using --fp4.") - - kwargs_run_demo = { - "prompt": prompt, - "prompt2": prompt2, - "height": args.height, - "width": args.width, - "batch_count": args.batch_count, - "num_warmup_runs": args.num_warmup_runs, - "use_cuda_graph": args.use_cuda_graph, - "image_strength": args.image_strength, - } - - # Add the appropriate image parameter based on pipeline type - if not args.version == "flux.1-kontext-dev": - kwargs_run_demo["input_image"] = args.input_image - kwargs_run_demo["control_image"] = args.control_image - - return kwargs_run_demo - - -if __name__ == "__main__": - print("[I] Initializing Flux img2img demo using TensorRT") - args = parse_args() - - _, kwargs_load_engine, _ = dd_argparse.process_pipeline_args(args) - kwargs_run_demo = process_demo_args(args) - - # Initialize demo - pipeline_type = pipeline_module.PIPELINE_TYPE.IMG2IMG - if args.version == "flux.1-kontext-dev": - demo = pipeline_module.FluxKontextPipeline.FromArgs(args, pipeline_type=pipeline_type) - else: - demo = pipeline_module.FluxPipeline.FromArgs(args, pipeline_type=pipeline_type) - - # Load TensorRT engines and pytorch modules - demo.load_engines( - framework_model_dir=args.framework_model_dir, - **kwargs_load_engine, - ) - - if args.onnx_export_only: - print("[I] ONNX export completed. Exiting...") - demo.teardown() - exit(0) - - # Since VAE and VAE_encoder require by far the largest device memories, in low-vram mode - # we allocate the required device memory individually before each model is run. - if demo.low_vram: - demo.device_memory_sizes = demo.get_device_memory_sizes() - else: - _, shared_device_memory = cudart.cudaMalloc(demo.calculate_max_device_memory()) - demo.activate_engines(shared_device_memory) - - demo.load_resources(args.height, args.width, args.batch_size, args.seed) - - # Run inference - images = demo.run(**kwargs_run_demo) - - demo.teardown() - - # save images - demo.save_images(kwargs_run_demo["prompt"], images, check_integrity=(args.version == "flux.1-kontext-dev")) diff --git a/demo/Diffusion/demo_img2vid.py b/demo/Diffusion/demo_img2vid.py deleted file mode 100644 index e082b26e9..000000000 --- a/demo/Diffusion/demo_img2vid.py +++ /dev/null @@ -1,134 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("sd") - -import argparse - -from PIL import Image - -from demo_diffusion import dd_argparse -from demo_diffusion import image as image_module -from demo_diffusion import pipeline as pipeline_module - - -def parseArgs(): - parser = argparse.ArgumentParser(description="Options for Stable Diffusion Img2Vid Demo", conflict_handler='resolve') - parser = dd_argparse.add_arguments(parser) - parser.add_argument('--version', type=str, default="svd-xt-1.1", choices=["svd-xt-1.1"], help="Version of Stable Video Diffusion") - parser.add_argument('--input-image', type=str, default="", help="Path to the input image") - parser.add_argument('--height', type=int, default=576, help="Height of image to generate (must be multiple of 8)") - parser.add_argument('--width', type=int, default=1024, help="Width of image to generate (must be multiple of 8)") - parser.add_argument('--min-guidance-scale', type=float, default=1.0, help="The minimum guidance scale. Used for the classifier free guidance with first frame") - parser.add_argument('--max-guidance-scale', type=float, default=3.0, help="The maximum guidance scale. Used for the classifier free guidance with last frame") - parser.add_argument('--denoising-steps', type=int, default=25, help="Number of denoising steps") - parser.add_argument('--num-warmup-runs', type=int, default=1, help="Number of warmup runs before benchmarking performance") - return parser.parse_args() - -def process_pipeline_args(args): - - if not args.input_image: - args.input_image = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/svd/rocket.png?download=true" - if isinstance(args.input_image, str): - input_image = image_module.download_image(args.input_image).resize((args.width, args.height)) - elif isinstance(args.input_image, Image.Image): - input_image = Image.open(args.input_image) - else: - raise ValueError(f"Input image(s) must be of type `PIL.Image.Image` or `str` (URL) but is {type(args.input_image)}") - - if args.height % 8 != 0 or args.width % 8 != 0: - raise ValueError(f"Image height and width have to be divisible by 8 but are: {args.image_height} and {args.width}.") - - # TODO enable BS>1 - max_batch_size = 1 - args.build_static_batch = True - - if args.batch_size > max_batch_size: - raise ValueError(f"Batch size {args.batch_size} is larger than allowed {max_batch_size}.") - - if not args.build_static_batch or args.build_dynamic_shape: - raise ValueError("Dynamic shapes not supported. Do not specify `--build-dynamic-shape`") - - if args.fp8: - import torch - device_info = torch.cuda.get_device_properties(0) - version = device_info.major * 10 + device_info.minor - if version < 90: # FP8 is only supppoted on Hopper. - raise ValueError(f"Cannot apply FP8 quantization for GPU with compute capability {version / 10.0}. FP8 is only supppoted on Hopper.") - args.optimization_level = 4 - print(f"[I] The default optimization level has been set to {args.optimization_level} for FP8.") - - if args.quantization_level == 0.0 and args.fp8: - args.quantization_level = 3.0 - print("[I] The default quantization level has been set to 3.0 for FP8.") - - kwargs_init_pipeline = { - 'version': args.version, - 'max_batch_size': max_batch_size, - 'denoising_steps': args.denoising_steps, - 'scheduler': args.scheduler, - 'min_guidance_scale': args.min_guidance_scale, - 'max_guidance_scale': args.max_guidance_scale, - 'output_dir': args.output_dir, - 'hf_token': args.hf_token, - 'verbose': args.verbose, - 'nvtx_profile': args.nvtx_profile, - 'use_cuda_graph': args.use_cuda_graph, - 'framework_model_dir': args.framework_model_dir, - 'torch_inference': args.torch_inference, - } - - kwargs_load_engine = { - 'onnx_opset': args.onnx_opset, - 'opt_batch_size': args.batch_size, - 'opt_image_height': args.height, - 'opt_image_width': args.width, - 'static_batch': args.build_static_batch, - 'static_shape': not args.build_dynamic_shape, - 'enable_all_tactics': args.build_all_tactics, - 'enable_refit': args.build_enable_refit, - 'timing_cache': args.timing_cache, - 'fp8': args.fp8, - 'quantization_level': args.quantization_level, - - } - - args_run_demo = (input_image, args.height, args.width, args.batch_size, args.batch_count, args.num_warmup_runs, args.use_cuda_graph) - - return kwargs_init_pipeline, kwargs_load_engine, args_run_demo - -if __name__ == "__main__": - print("[I] Initializing StableDiffusion img2vid demo using TensorRT") - args = parseArgs() - kwargs_init_pipeline, kwargs_load_engine, args_run_demo = process_pipeline_args(args) - # Initialize demo - demo = pipeline_module.StableVideoDiffusionPipeline( - pipeline_type=pipeline_module.PIPELINE_TYPE.IMG2VID, **kwargs_init_pipeline - ) - demo.loadEngines( - args.engine_dir, - args.framework_model_dir, - args.onnx_dir, - **kwargs_load_engine) - demo.loadResources(args.height, args.width, args.batch_size, args.seed) - - # Run inference - demo.run(*args_run_demo) - - demo.teardown() diff --git a/demo/Diffusion/demo_stable_cascade.py b/demo/Diffusion/demo_stable_cascade.py deleted file mode 100644 index 9ad0d9636..000000000 --- a/demo/Diffusion/demo_stable_cascade.py +++ /dev/null @@ -1,165 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("sd") - -import argparse -import os - -import torch -from cuda.bindings import runtime as cudart - -from demo_diffusion import dd_argparse -from demo_diffusion import pipeline as pipeline_module - - -def parseArgs(): - parser = argparse.ArgumentParser(description="Options for Stable Cascade Txt2Img Demo", conflict_handler='resolve') - parser = dd_argparse.add_arguments(parser) - parser.add_argument('--version', type=str, default="cascade", choices=["cascade"], help="Version of Stable Cascade") - parser.add_argument('--height', type=int, default=1024, help="Height of image to generate (must be multiple of 8)") - parser.add_argument('--width', type=int, default=1024, help="Width of image to generate (must be multiple of 8)") - parser.add_argument('--lite', action='store_true', help="Use the Lite Version of the Stage B and Stage C models") - parser.add_argument('--prior-guidance-scale', type=float, default=4.0, help="Value of classifier-free guidance scale for the prior") - parser.add_argument('--decoder-guidance-scale', type=float, default=0.0, help="Value of classifier-free guidance scale for the decoder") - parser.add_argument('--prior-denoising-steps', type=int, default=20, help="Number of denoising steps for the prior") - parser.add_argument('--decoder-denoising-steps', type=int, default=10, help="Number of denoising steps for the decoder") - return parser.parse_args() - - -class StableCascadeDemoPipeline(pipeline_module.StableCascadePipeline): - def __init__(self, prior_denoising_steps, decoder_denoising_steps, prior_guidance_scale, decoder_guidance_scale, lite, **kwargs): - self.nvtx_profile = kwargs['nvtx_profile'] - self.prior = pipeline_module.StableCascadePipeline( - pipeline_type=pipeline_module.PIPELINE_TYPE.CASCADE_PRIOR, - denoising_steps=prior_denoising_steps, - guidance_scale=prior_guidance_scale, - return_latents=True, - lite=lite, - **kwargs, - ) - self.decoder = pipeline_module.StableCascadePipeline( - pipeline_type=pipeline_module.PIPELINE_TYPE.CASCADE_DECODER, - denoising_steps=decoder_denoising_steps, - guidance_scale=decoder_guidance_scale, - lite=lite, - **kwargs, - ) - - def loadEngines(self, framework_model_dir, onnx_dir, engine_dir, **kwargs): - prior_suffix = "prior_lite" if self.prior.lite else "prior" - decoder_suffix = "decoder_lite" if self.decoder.lite else "decoder" - self.prior.loadEngines( - os.path.join(engine_dir, prior_suffix), - framework_model_dir, - os.path.join(onnx_dir, prior_suffix), - **kwargs) - self.decoder.loadEngines( - os.path.join(engine_dir, decoder_suffix), - framework_model_dir, - os.path.join(onnx_dir, decoder_suffix), - **kwargs) - - def activateEngines(self, shared_device_memory=None): - self.prior.activateEngines(shared_device_memory) - self.decoder.activateEngines(shared_device_memory) - - def loadResources(self, image_height, image_width, batch_size, seed): - self.prior.loadResources(image_height, image_width, batch_size, seed) - # Use a different seed for decoder - self.decoder.loadResources(image_height, image_width, batch_size, ((seed+1) if seed is not None else None)) - - def get_max_device_memory(self): - max_device_memory = self.prior.calculateMaxDeviceMemory() - max_device_memory = max(max_device_memory, self.decoder.calculateMaxDeviceMemory()) - return max_device_memory - - def run(self, prompt, negative_prompt, height, width, batch_size, batch_count, num_warmup_runs, use_cuda_graph): - # Process prompt - if not isinstance(prompt, list): - raise ValueError(f"`prompt` must be of type `str` list, but is {type(prompt)}") - prompt = prompt * batch_size - - if not isinstance(negative_prompt, list): - raise ValueError(f"`--negative-prompt` must be of type `str` list, but is {type(negative_prompt)}") - if len(negative_prompt) == 1: - negative_prompt = negative_prompt * batch_size - - num_warmup_runs = max(1, num_warmup_runs) if use_cuda_graph else num_warmup_runs - if num_warmup_runs > 0: - print("[I] Warming up ..") - for _ in range(num_warmup_runs): - latents, _ = self.prior.infer(prompt, negative_prompt, height, width, warmup=True) - latents = latents.to(torch.float16) if self.decoder.fp16 else latents - images, _ = self.decoder.infer(prompt, negative_prompt, height, width, image_embeddings=latents, warmup=True) - - for _ in range(batch_count): - print("[I] Running Stable Cascade pipeline") - if self.nvtx_profile: - cudart.cudaProfilerStart() - latents, time_prior = self.prior.infer(prompt, negative_prompt, height, width, warmup=False) - latents = latents.to(torch.float16) if self.decoder.fp16 else latents - images, time_decoder = self.decoder.infer(prompt, negative_prompt, height, width, image_embeddings=latents, warmup=False) - - if self.nvtx_profile: - cudart.cudaProfilerStop() - print('|-----------------|--------------|') - print('| {:^15} | {:>9.2f} ms |'.format('e2e', time_prior + time_decoder)) - print('|-----------------|--------------|') - - def teardown(self): - self.prior.teardown() - self.decoder.teardown() - - -if __name__ == "__main__": - print("[I] Initializing StableCascade txt2img demo using TensorRT") - args = parseArgs() - - kwargs_init_pipeline, kwargs_load_engine, args_run_demo = dd_argparse.process_pipeline_args(args) - - # Initialize demo - _ = kwargs_init_pipeline.pop('guidance_scale') - _ = kwargs_init_pipeline.pop('denoising_steps') - demo = StableCascadeDemoPipeline( - args.prior_denoising_steps, - args.decoder_denoising_steps, - args.prior_guidance_scale, - args.decoder_guidance_scale, - args.lite, - **kwargs_init_pipeline - ) - - # Load TensorRT engines and pytorch modules - demo.loadEngines( - args.framework_model_dir, - args.onnx_dir, - args.engine_dir, - **kwargs_load_engine, - ) - - # Load resources - _, shared_device_memory = cudart.cudaMalloc(demo.get_max_device_memory()) - demo.activateEngines(shared_device_memory) - demo.loadResources(args.height, args.width, args.batch_size, args.seed) - - # Run inference - demo.run(*args_run_demo) - - demo.teardown() diff --git a/demo/Diffusion/demo_txt2image_cosmos.py b/demo/Diffusion/demo_txt2image_cosmos.py deleted file mode 100644 index 17d914562..000000000 --- a/demo/Diffusion/demo_txt2image_cosmos.py +++ /dev/null @@ -1,151 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("cosmos") - -import argparse - -from cuda.bindings import runtime as cudart - -from demo_diffusion import dd_argparse -from demo_diffusion import pipeline as pipeline_module - - -def parse_args(): - parser = argparse.ArgumentParser(description="Options for Cosmos text2image Demo", conflict_handler="resolve") - parser = dd_argparse.add_arguments(parser) - parser.add_argument( - "--version", - type=str, - default="cosmos-predict2-2b-text2image", - choices=("cosmos-predict2-2b-text2image", "cosmos-predict2-14b-text2image"), - help="Version of Cosmos", - ) - parser.add_argument( - "--height", - type=int, - default=768, - help="Height of image to generate (must be multiple of 8)", - ) - parser.add_argument( - "--width", - type=int, - default=1360, - help="Width of image to generate (must be multiple of 8)", - ) - parser.add_argument("--denoising-steps", type=int, default=35, help="Number of denoising steps") - parser.add_argument( - "--guidance-scale", - type=float, - default=7.0, - help="Value of classifier-free guidance scale (must be greater than 1)", - ) - parser.add_argument( - "--num-images-per-prompt", type=int, default=1, help="The number of images to generate per prompt." - ) - parser.add_argument( - "--max_sequence_length", - type=int, - default=512, - help="Maximum sequence length to use with the prompt.", - ) - parser.add_argument( - "--t5-ws-percentage", - type=int, - default=None, - help="Set runtime weight streaming budget as the percentage of the size of streamable weights for the T5 model. This argument only takes effect when --ws is set. 0 streams the most weights and 100 or None streams no weights. ", - ) - parser.add_argument( - "--transformer-ws-percentage", - type=int, - default=None, - help="Set runtime weight streaming budget as the percentage of the size of streamable weights for the transformer model. This argument only takes effect when --ws is set. 0 streams the most weights and 100 or None streams no weights.", - ) - parser.add_argument( - "--bf16", - action="store_true", - default=True, - help="Use bfloat16 precision by default.", - ) - return parser.parse_args() - - -def process_demo_args(args): - batch_size = args.batch_size - prompt = args.prompt - negative_prompt = args.negative_prompt - # Process input args - if not isinstance(prompt, list): - raise ValueError(f"`prompt` must be of type `str` list, but is {type(prompt)}") - prompt = prompt * batch_size - if not isinstance(negative_prompt, list): - raise ValueError(f"`negative_prompt` must be of type `str` list, but is {type(negative_prompt)}") - negative_prompt = negative_prompt * batch_size - - kwargs_run_demo = { - "prompt": prompt, - "negative_prompt": negative_prompt, - "height": args.height, - "width": args.width, - "batch_count": args.batch_count, - "num_warmup_runs": args.num_warmup_runs, - "use_cuda_graph": args.use_cuda_graph, - "num_images_per_prompt": args.num_images_per_prompt, - } - - return kwargs_run_demo - - -if __name__ == "__main__": - print("[I] Initializing Cosmos text2image demo using TensorRT") - args = parse_args() - - _, kwargs_load_engine, _ = dd_argparse.process_pipeline_args(args) - kwargs_run_demo = process_demo_args(args) - - # Initialize demo - demo = pipeline_module.CosmosPipeline.FromArgs(args, pipeline_type=pipeline_module.PIPELINE_TYPE.TXT2IMG) - - # Load TensorRT engines and pytorch modules - demo.load_engines( - framework_model_dir=args.framework_model_dir, - **kwargs_load_engine, - ) - - if args.onnx_export_only: - print("[I] ONNX export completed. Exiting...") - demo.teardown() - exit(0) - - # In low-vram mode we allocate the required device memory individually before each model is run. - if demo.low_vram: - demo.device_memory_sizes = demo.get_device_memory_sizes() - else: - _, shared_device_memory = cudart.cudaMalloc(demo.calculate_max_device_memory()) - demo.activate_engines(shared_device_memory) - - demo.load_resources(args.height, args.width, args.batch_size, args.seed) - - # Run inference - images = demo.run(**kwargs_run_demo) - - demo.teardown() - - # save images - demo.save_images(kwargs_run_demo["prompt"], images, check_integrity=True) diff --git a/demo/Diffusion/demo_txt2img.py b/demo/Diffusion/demo_txt2img.py deleted file mode 100644 index d980d8642..000000000 --- a/demo/Diffusion/demo_txt2img.py +++ /dev/null @@ -1,61 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("sd") - -import argparse - -from cuda.bindings import runtime as cudart - -from demo_diffusion import dd_argparse -from demo_diffusion import pipeline as pipeline_module - - -def parseArgs(): - parser = argparse.ArgumentParser(description="Options for Stable Diffusion Txt2Img Demo") - parser = dd_argparse.add_arguments(parser) - return parser.parse_args() - -if __name__ == "__main__": - print("[I] Initializing StableDiffusion txt2img demo using TensorRT") - args = parseArgs() - - kwargs_init_pipeline, kwargs_load_engine, args_run_demo = dd_argparse.process_pipeline_args(args) - - # Initialize demo - demo = pipeline_module.StableDiffusionPipeline( - pipeline_type=pipeline_module.PIPELINE_TYPE.TXT2IMG, **kwargs_init_pipeline - ) - - # Load TensorRT engines and pytorch modules - demo.loadEngines( - args.engine_dir, - args.framework_model_dir, - args.onnx_dir, - **kwargs_load_engine) - - # Load resources - _, shared_device_memory = cudart.cudaMalloc(demo.calculateMaxDeviceMemory()) - demo.activateEngines(shared_device_memory) - demo.loadResources(args.height, args.width, args.batch_size, args.seed) - - # Run inference - demo.run(*args_run_demo) - - demo.teardown() diff --git a/demo/Diffusion/demo_txt2img_flux.py b/demo/Diffusion/demo_txt2img_flux.py deleted file mode 100644 index 0236ba323..000000000 --- a/demo/Diffusion/demo_txt2img_flux.py +++ /dev/null @@ -1,171 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("flux") - -import argparse - -from cuda.bindings import runtime as cudart - -from demo_diffusion import dd_argparse -from demo_diffusion import pipeline as pipeline_module - - -def parse_args(): - parser = argparse.ArgumentParser( - description="Options for Flux Txt2Img Demo", conflict_handler="resolve" - ) - parser = dd_argparse.add_arguments(parser) - parser.add_argument( - "--version", - type=str, - default="flux.1-dev", - choices=("flux.1-dev", "flux.1-schnell"), - help="Version of Flux", - ) - parser.add_argument( - "--prompt2", - default=None, - nargs="*", - help="Text prompt(s) to be sent to the T5 tokenizer and text encoder. If not defined, prompt will be used instead", - ) - parser.add_argument( - "--height", - type=int, - default=1024, - help="Height of image to generate (must be multiple of 8)", - ) - parser.add_argument( - "--width", - type=int, - default=1024, - help="Width of image to generate (must be multiple of 8)", - ) - parser.add_argument( - "--denoising-steps", type=int, default=50, help="Number of denoising steps" - ) - parser.add_argument( - "--guidance-scale", - type=float, - default=3.5, - help="Value of classifier-free guidance scale (must be greater than 1)", - ) - parser.add_argument( - "--max_sequence_length", - type=int, - help="Maximum sequence length to use with the prompt. Can be up to 512 for the dev and 256 for the schnell variant.", - ) - parser.add_argument( - "--t5-ws-percentage", - type=int, - default=None, - help="Set runtime weight streaming budget as the percentage of the size of streamable weights for the T5 model. This argument only takes effect when --ws is set. 0 streams the most weights and 100 or None streams no weights. ", - ) - parser.add_argument( - "--transformer-ws-percentage", - type=int, - default=None, - help="Set runtime weight streaming budget as the percentage of the size of streamable weights for the transformer model. This argument only takes effect when --ws is set. 0 streams the most weights and 100 or None streams no weights." - ) - - return parser.parse_args() - - -def process_demo_args(args): - batch_size = args.batch_size - prompt = args.prompt - # If prompt2 is not defined, use prompt instead - prompt2 = args.prompt2 or prompt - - # Process input args - if not isinstance(prompt, list): - raise ValueError(f"`prompt` must be of type `str` list, but is {type(prompt)}") - prompt = prompt * batch_size - - if not isinstance(prompt2, list): - raise ValueError( - f"`prompt2` must be of type `str` list, but is {type(prompt2)}" - ) - if len(prompt2) == 1: - prompt2 = prompt2 * batch_size - - max_seq_supported_by_model = { - "flux.1-schnell": 256, - "flux.1-dev": 512, - }[args.version] - if args.max_sequence_length is not None: - if args.max_sequence_length > max_seq_supported_by_model: - raise ValueError( - f"For {args.version}, `max_sequence_length` cannot be greater than {max_seq_supported_by_model} but is {args.max_sequence_length}" - ) - else: - args.max_sequence_length = max_seq_supported_by_model - - kwargs_run_demo = { - "prompt": prompt, - "prompt2": prompt2, - "height": args.height, - "width": args.width, - "batch_count": args.batch_count, - "num_warmup_runs": args.num_warmup_runs, - "use_cuda_graph": args.use_cuda_graph, - } - - return kwargs_run_demo - - -if __name__ == "__main__": - print("[I] Initializing Flux txt2img demo using TensorRT") - args = parse_args() - - _, kwargs_load_engine, _ = dd_argparse.process_pipeline_args(args) - kwargs_run_demo = process_demo_args(args) - - # Initialize demo - pipeline_type = pipeline_module.PIPELINE_TYPE.TXT2IMG - demo = pipeline_module.FluxPipeline.FromArgs(args, pipeline_type=pipeline_type) - - # Load TensorRT engines and pytorch modules - demo.load_engines( - framework_model_dir=args.framework_model_dir, - **kwargs_load_engine, - ) - - if args.onnx_export_only: - print("[I] ONNX export completed. Exiting...") - demo.teardown() - exit(0) - - # Since VAE and VAE_encoder require by far the largest device memories, in low-vram mode - # we allocate the required device memory individually before each model is run. - if demo.low_vram: - demo.device_memory_sizes = demo.get_device_memory_sizes() - else: - _, shared_device_memory = cudart.cudaMalloc(demo.calculate_max_device_memory()) - demo.activate_engines(shared_device_memory) - - demo.load_resources(args.height, args.width, args.batch_size, args.seed) - - # Run inference - images = demo.run(**kwargs_run_demo) - - demo.teardown() - - # save images - demo.save_images(kwargs_run_demo["prompt"], images) diff --git a/demo/Diffusion/demo_txt2img_sd3.py b/demo/Diffusion/demo_txt2img_sd3.py deleted file mode 100644 index 5ceda2239..000000000 --- a/demo/Diffusion/demo_txt2img_sd3.py +++ /dev/null @@ -1,130 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("sd") - -import argparse - -from cuda.bindings import runtime as cudart -from PIL import Image - -from demo_diffusion import dd_argparse -from demo_diffusion import pipeline as pipeline_module -from demo_diffusion.utils_sd3.other_impls import preprocess_image_sd3 - - -def parseArgs(): - # Stable Diffusion 3 configuration - parser = argparse.ArgumentParser(description="Options for Stable Diffusion 3 Txt2Img Demo", conflict_handler='resolve') - parser = dd_argparse.add_arguments(parser) - parser.add_argument('--version', type=str, default="sd3", choices=["sd3"], help="Version of Stable Diffusion") - parser.add_argument('--height', type=int, default=1024, help="Height of image to generate (must be multiple of 8)") - parser.add_argument('--width', type=int, default=1024, help="Height of image to generate (must be multiple of 8)") - parser.add_argument('--shift', type=int, default=1.0, help="Shift parameter for SD3") - parser.add_argument('--cfg-scale', type=int, default=5, help="CFG Scale for SD3") - parser.add_argument('--denoising-steps', type=int, default=50, help="Number of denoising steps") - parser.add_argument('--denoising-percentage', type=float, default=0.6, help="Percentage of denoising steps to run. This parameter is only used if input-image is provided") - parser.add_argument('--input-image', type=str, default="", help="Path to the input image") - - return parser.parse_args() - -def process_pipeline_args(args): - if args.height % 8 != 0 or args.width % 8 != 0: - raise ValueError(f"Image height and width have to be divisible by 8 but specified as: {args.image_height} and {args.width}.") - - max_batch_size = 4 - if args.batch_size > max_batch_size: - raise ValueError(f"Batch size {args.batch_size} is larger than allowed {max_batch_size}.") - - if args.use_cuda_graph and (not args.build_static_batch or args.build_dynamic_shape): - raise ValueError( - "Using CUDA graph requires static dimensions. Enable `--build-static-batch` and do not specify `--build-dynamic-shape`" - ) - - input_image = None - if args.input_image: - input_image = Image.open(args.input_image) - - image_width, image_height = input_image.size - if image_height != args.height or image_width != args.width: - print(f"[I] Resizing input_image to {args.height}x{args.width}") - input_image = input_image.resize((args.width, args.height), Image.LANCZOS) - image_height, image_width = args.height, args.width - - input_image = preprocess_image_sd3(input_image) - - kwargs_init_pipeline = { - 'version': args.version, - 'max_batch_size': max_batch_size, - 'output_dir': args.output_dir, - 'hf_token': args.hf_token, - 'verbose': args.verbose, - 'nvtx_profile': args.nvtx_profile, - 'use_cuda_graph': args.use_cuda_graph, - 'framework_model_dir': args.framework_model_dir, - 'torch_inference': args.torch_inference, - 'shift': args.shift, - 'cfg_scale': args.cfg_scale, - 'denoising_steps': args.denoising_steps, - 'denoising_percentage': args.denoising_percentage, - 'input_image': input_image - } - - kwargs_load_engine = { - 'onnx_opset': args.onnx_opset, - 'opt_batch_size': args.batch_size, - 'opt_image_height': args.height, - 'opt_image_width': args.width, - 'static_batch': args.build_static_batch, - 'static_shape': not args.build_dynamic_shape, - 'enable_all_tactics': args.build_all_tactics, - 'timing_cache': args.timing_cache, - } - - args_run_demo = (args.prompt, args.negative_prompt, args.height, args.width, args.batch_size, args.batch_count, args.num_warmup_runs, args.use_cuda_graph) - - return kwargs_init_pipeline, kwargs_load_engine, args_run_demo - -if __name__ == "__main__": - print("[I] Initializing Stable Diffusion 3 demo using TensorRT") - args = parseArgs() - - kwargs_init_pipeline, kwargs_load_engine, args_run_demo = process_pipeline_args(args) - - # Initialize demo - demo = pipeline_module.StableDiffusion3Pipeline( - pipeline_type=pipeline_module.PIPELINE_TYPE.TXT2IMG, **kwargs_init_pipeline - ) - - # Load TensorRT engines and pytorch modules - demo.loadEngines( - args.engine_dir, - args.framework_model_dir, - args.onnx_dir, - **kwargs_load_engine) - - # Load resources - _, shared_device_memory = cudart.cudaMalloc(demo.calculateMaxDeviceMemory()) - demo.activateEngines(shared_device_memory) - demo.loadResources(args.height, args.width, args.batch_size, args.seed) - - # Run inference - demo.run(*args_run_demo) - - demo.teardown() diff --git a/demo/Diffusion/demo_txt2img_sd35.py b/demo/Diffusion/demo_txt2img_sd35.py deleted file mode 100644 index 5de73625f..000000000 --- a/demo/Diffusion/demo_txt2img_sd35.py +++ /dev/null @@ -1,135 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("sd") - -import argparse - -from cuda.bindings import runtime as cudart - -from demo_diffusion import dd_argparse -from demo_diffusion import pipeline as pipeline_module - - -def parseArgs(): - # Stable Diffusion 3.5 configuration - parser = argparse.ArgumentParser( - description="Options for Stable Diffusion 3.5 Txt2Img Demo", conflict_handler="resolve" - ) - parser = dd_argparse.add_arguments(parser) - parser.add_argument( - "--version", - type=str, - default="3.5-medium", - choices={"3.5-medium", "3.5-large"}, - help="Version of Stable Diffusion 3.5", - ) - parser.add_argument("--height", type=int, default=1024, help="Height of image to generate (must be multiple of 8)") - parser.add_argument("--width", type=int, default=1024, help="Height of image to generate (must be multiple of 8)") - parser.add_argument( - "--guidance-scale", - type=float, - default=7.0, - help="Value of classifier-free guidance scale (must be greater than 1)", - ) - parser.add_argument( - "--max-sequence-length", - type=int, - default=256, - help="Maximum sequence length to use with the prompt.", - ) - parser.add_argument("--denoising-steps", type=int, default=50, help="Number of denoising steps") - - return parser.parse_args() - -def process_demo_args(args): - batch_size = args.batch_size - prompt = args.prompt - negative_prompt = args.negative_prompt - # Process prompt - if not isinstance(prompt, list): - raise ValueError(f"`prompt` must be of type `str` list, but is {type(prompt)}") - prompt = prompt * batch_size - - if not isinstance(negative_prompt, list): - raise ValueError(f"`--negative-prompt` must be of type `str` list, but is {type(negative_prompt)}") - if len(negative_prompt) == 1: - negative_prompt = negative_prompt * batch_size - - if args.height % 8 != 0 or args.width % 8 != 0: - raise ValueError( - f"Image height and width have to be divisible by 8 but specified as: {args.image_height} and {args.width}." - ) - - max_batch_size = 4 - if args.batch_size > max_batch_size: - raise ValueError(f"Batch size {args.batch_size} is larger than allowed {max_batch_size}.") - - if args.use_cuda_graph and (not args.build_static_batch or args.build_dynamic_shape): - raise ValueError( - "Using CUDA graph requires static dimensions. Enable `--build-static-batch` and do not specify `--build-dynamic-shape`" - ) - - kwargs_run_demo = { - "prompt": prompt, - "negative_prompt": negative_prompt, - "height": args.height, - "width": args.width, - "batch_count": args.batch_count, - "num_warmup_runs": args.num_warmup_runs, - "use_cuda_graph": args.use_cuda_graph, - } - - return kwargs_run_demo - - -if __name__ == "__main__": - print("[I] Initializing Stable Diffusion 3.5 demo using TensorRT") - args = parseArgs() - - _, kwargs_load_engine, _ = dd_argparse.process_pipeline_args(args) - kwargs_run_demo = process_demo_args(args) - - # Initialize demo - demo = pipeline_module.StableDiffusion35Pipeline.FromArgs(args, pipeline_type=pipeline_module.PIPELINE_TYPE.TXT2IMG) - - # Load TensorRT engines and pytorch modules - demo.load_engines( - framework_model_dir=args.framework_model_dir, - **kwargs_load_engine, - ) - - if demo.low_vram: - demo.device_memory_sizes = demo.get_device_memory_sizes() - else: - _, shared_device_memory = cudart.cudaMalloc(demo.calculate_max_device_memory()) - demo.activate_engines(shared_device_memory) - - # Load resources - demo.load_resources( - image_height=args.height, - image_width=args.width, - batch_size=args.batch_size, - seed=args.seed, - ) - - # Run inference - demo.run(**kwargs_run_demo) - - demo.teardown() diff --git a/demo/Diffusion/demo_txt2img_xl.py b/demo/Diffusion/demo_txt2img_xl.py deleted file mode 100644 index e48288dc0..000000000 --- a/demo/Diffusion/demo_txt2img_xl.py +++ /dev/null @@ -1,160 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("sd") - -import argparse - -from cuda.bindings import runtime as cudart - -from demo_diffusion import dd_argparse -from demo_diffusion import pipeline as pipeline_module - - -def parseArgs(): - parser = argparse.ArgumentParser(description="Options for Stable Diffusion XL Txt2Img Demo", conflict_handler='resolve') - parser = dd_argparse.add_arguments(parser) - parser.add_argument('--version', type=str, default="xl-1.0", choices=["xl-1.0", "xl-turbo"], help="Version of Stable Diffusion XL") - parser.add_argument('--height', type=int, default=1024, help="Height of image to generate (must be multiple of 8)") - parser.add_argument('--width', type=int, default=1024, help="Height of image to generate (must be multiple of 8)") - parser.add_argument('--num-warmup-runs', type=int, default=1, help="Number of warmup runs before benchmarking performance") - - parser.add_argument('--guidance-scale', type=float, default=5.0, help="Value of classifier-free guidance scale (must be greater than 1)") - - parser.add_argument('--enable-refiner', action='store_true', help="Enable SDXL-Refiner model") - parser.add_argument('--image-strength', type=float, default=0.3, help="Strength of transformation applied to input_image (must be between 0 and 1)") - parser.add_argument('--onnx-refiner-dir', default='onnx_xl_refiner', help="Directory for SDXL-Refiner ONNX models") - parser.add_argument('--engine-refiner-dir', default='engine_xl_refiner', help="Directory for SDXL-Refiner TensorRT engines") - - return parser.parse_args() - - -class StableDiffusionXLPipeline(pipeline_module.StableDiffusionPipeline): - def __init__(self, vae_scaling_factor=0.13025, enable_refiner=False, **kwargs): - self.enable_refiner = enable_refiner - self.nvtx_profile = kwargs['nvtx_profile'] - self.base = pipeline_module.StableDiffusionPipeline( - pipeline_type=pipeline_module.PIPELINE_TYPE.XL_BASE, - vae_scaling_factor=vae_scaling_factor, - return_latents=self.enable_refiner, - **kwargs, - ) - if self.enable_refiner: - self.refiner = pipeline_module.StableDiffusionPipeline( - pipeline_type=pipeline_module.PIPELINE_TYPE.XL_REFINER, - vae_scaling_factor=vae_scaling_factor, - return_latents=False, - **kwargs, - ) - - def loadEngines(self, framework_model_dir, onnx_dir, engine_dir, onnx_refiner_dir='onnx_xl_refiner', engine_refiner_dir='engine_xl_refiner', **kwargs): - self.base.loadEngines(engine_dir, framework_model_dir, onnx_dir, **kwargs) - if self.enable_refiner: - self.refiner.loadEngines(engine_refiner_dir, framework_model_dir, onnx_refiner_dir, **kwargs) - - def activateEngines(self, shared_device_memory=None): - self.base.activateEngines(shared_device_memory) - if self.enable_refiner: - self.refiner.activateEngines(shared_device_memory) - - def loadResources(self, image_height, image_width, batch_size, seed): - self.base.loadResources(image_height, image_width, batch_size, seed) - if self.enable_refiner: - # Use a different seed for refiner - we arbitrarily use base seed+1, if specified. - self.refiner.loadResources(image_height, image_width, batch_size, ((seed+1) if seed is not None else None)) - - def get_max_device_memory(self): - max_device_memory = self.base.calculateMaxDeviceMemory() - if self.enable_refiner: - max_device_memory = max(max_device_memory, self.refiner.calculateMaxDeviceMemory()) - return max_device_memory - - def run(self, prompt, negative_prompt, height, width, batch_size, batch_count, num_warmup_runs, use_cuda_graph, **kwargs_infer_refiner): - # Process prompt - if not isinstance(prompt, list): - raise ValueError(f"`prompt` must be of type `str` list, but is {type(prompt)}") - prompt = prompt * batch_size - - if not isinstance(negative_prompt, list): - raise ValueError(f"`--negative-prompt` must be of type `str` list, but is {type(negative_prompt)}") - if len(negative_prompt) == 1: - negative_prompt = negative_prompt * batch_size - - num_warmup_runs = max(1, num_warmup_runs) if use_cuda_graph else num_warmup_runs - if num_warmup_runs > 0: - print("[I] Warming up ..") - for _ in range(num_warmup_runs): - images, _ = self.base.infer(prompt, negative_prompt, height, width, warmup=True) - if args.enable_refiner: - images, _ = self.refiner.infer(prompt, negative_prompt, height, width, input_image=images, warmup=True, **kwargs_infer_refiner) - - ret = [] - for _ in range(batch_count): - print("[I] Running StableDiffusionXL pipeline") - if self.nvtx_profile: - cudart.cudaProfilerStart() - latents, time_base = self.base.infer(prompt, negative_prompt, height, width, warmup=False) - if self.enable_refiner: - images, time_refiner = self.refiner.infer(prompt, negative_prompt, height, width, input_image=latents, warmup=False, **kwargs_infer_refiner) - ret.append(images) - else: - ret.append(latents) - - if self.nvtx_profile: - cudart.cudaProfilerStop() - if self.enable_refiner: - print('|-----------------|--------------|') - print('| {:^15} | {:>9.2f} ms |'.format('e2e', time_base + time_refiner)) - print('|-----------------|--------------|') - return ret - - def teardown(self): - self.base.teardown() - if self.enable_refiner: - self.refiner.teardown() - - -if __name__ == "__main__": - print("[I] Initializing TensorRT accelerated StableDiffusionXL txt2img pipeline") - args = parseArgs() - - kwargs_init_pipeline, kwargs_load_engine, args_run_demo = dd_argparse.process_pipeline_args(args) - - # Initialize demo - demo = StableDiffusionXLPipeline(vae_scaling_factor=0.13025, enable_refiner=args.enable_refiner, **kwargs_init_pipeline) - - # Load TensorRT engines and pytorch modules - kwargs_load_refiner = {'onnx_refiner_dir': args.onnx_refiner_dir, 'engine_refiner_dir': args.engine_refiner_dir} if args.enable_refiner else {} - demo.loadEngines( - args.framework_model_dir, - args.onnx_dir, - args.engine_dir, - **kwargs_load_refiner, - **kwargs_load_engine) - - # Load resources - _, shared_device_memory = cudart.cudaMalloc(demo.get_max_device_memory()) - demo.activateEngines(shared_device_memory) - demo.loadResources(args.height, args.width, args.batch_size, args.seed) - - # Run inference - kwargs_infer_refiner = {'image_strength': args.image_strength} if args.enable_refiner else {} - demo.run(*args_run_demo, **kwargs_infer_refiner) - - demo.teardown() diff --git a/demo/Diffusion/demo_txt2vid_wan.py b/demo/Diffusion/demo_txt2vid_wan.py deleted file mode 100644 index 71660f392..000000000 --- a/demo/Diffusion/demo_txt2vid_wan.py +++ /dev/null @@ -1,128 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("cosmos") - -import argparse - -from cuda.bindings import runtime as cudart - -from demo_diffusion import dd_argparse -from demo_diffusion import pipeline as pipeline_module - - -def parseArgs(): - parser = argparse.ArgumentParser(description="Options for Wan 2.2 Txt2Vid Demo", conflict_handler='resolve') - parser = dd_argparse.add_arguments(parser) - parser.add_argument('--version', type=str, default="wan2.2-t2v-a14b", help="Version of Wan") - parser.add_argument('--guidance-scale', type=float, default=4.0, help="Guidance scale for high-noise stage (Wan default: 4.0)") - parser.add_argument('--guidance-scale-2', type=float, default=3.0, help="Guidance scale for low-noise stage (Wan default: 3.0)") - parser.add_argument('--boundary-ratio', type=float, default=0.875, help="Boundary ratio for two-stage denoising (default: 0.875)") - parser.add_argument('--denoising-steps', type=int, default=40, help="Number of denoising steps (Wan default: 40)") - parser.add_argument('--num-warmup-runs', type=int, default=1, help="Number of warmup runs before benchmarking") - parser.add_argument( - '--negative-prompt', - nargs='*', - default= ( - "vivid colors, overexposed, static, blurry details, subtitles, style, " - "work of art, painting, picture, still, overall grayish, worst quality, " - "low quality, JPEG artifacts, ugly, deformed, extra fingers, poorly drawn hands, " - "poorly drawn face, deformed, disfigured, deformed limbs, fused fingers, " - "static image, cluttered background, three legs, many people in the background, " - "walking backwards" - ), - help="Negative prompt (Wan team default, English translation)" - ) - parser.add_argument( - "--onnx-opset", - type=int, - default=23, - choices=range(7, 24), - help="Select ONNX opset version to target for exported models", - ) - return parser.parse_args() - - -def process_demo_args(args): - args.height = 720 - args.width = 1280 - args.num_frames = 81 - args.max_sequence_length = 512 - - # require static batch = 1 - if args.batch_size > 1: - raise ValueError(f"Batch size {args.batch_size} is larger than allowed (max=1 for Wan).") - args.batch_size = 1 - args.build_static_batch = True - args.build_dynamic_shape = False - - print(f"[I] Building Wan 2.2 T2V with fixed resolution: {args.height}×{args.width}, {args.num_frames} frames") - - negative_prompt = args.negative_prompt - if isinstance(negative_prompt, list): - negative_prompt = ' '.join(negative_prompt) if negative_prompt else "" - - kwargs_run_demo = { - 'prompt': args.prompt, - 'height': args.height, - 'width': args.width, - 'num_frames': args.num_frames, - 'batch_size': args.batch_size, - 'batch_count': args.batch_count, - 'num_warmup_runs': args.num_warmup_runs, - 'use_cuda_graph': args.use_cuda_graph, - 'negative_prompt': negative_prompt, - 'num_inference_steps': args.denoising_steps, - } - - return kwargs_run_demo - - -if __name__ == "__main__": - print("[I] Initializing Wan 2.2 txt2vid demo using TensorRT") - args = parseArgs() - - kwargs_run_demo = process_demo_args(args) - - _, kwargs_load_engine, _ = dd_argparse.process_pipeline_args(args) - - # Initialize demo - demo = pipeline_module.WanPipeline.FromArgs(args, pipeline_type=pipeline_module.PIPELINE_TYPE.TXT2VID) - - # Load TensorRT engines and pytorch modules - demo.load_engines( - framework_model_dir=args.framework_model_dir, - **kwargs_load_engine, - ) - - # In low-vram mode we allocate the required device memory individually before each model is run - if args.low_vram: - demo.device_memory_sizes = demo.get_device_memory_sizes() - else: - _, shared_device_memory = cudart.cudaMalloc(demo.calculate_max_device_memory()) - demo.activate_engines(shared_device_memory) - - # Load resources - demo.load_resources(args.height, args.width, args.batch_size, args.seed) - - # Run inference - demo.run(**kwargs_run_demo) - - demo.teardown() - diff --git a/demo/Diffusion/demo_vid2world_cosmos.py b/demo/Diffusion/demo_vid2world_cosmos.py deleted file mode 100644 index 734c04f23..000000000 --- a/demo/Diffusion/demo_vid2world_cosmos.py +++ /dev/null @@ -1,174 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Configure dependencies before any external imports -from demo_diffusion import deps -deps.configure("cosmos") - -import argparse - -from cuda.bindings import runtime as cudart -from diffusers.utils import load_image, load_video - -from demo_diffusion import dd_argparse -from demo_diffusion import pipeline as pipeline_module - - -def parse_args(): - parser = argparse.ArgumentParser(description="Options for Cosmos video2world Demo", conflict_handler="resolve") - parser = dd_argparse.add_arguments(parser) - parser.add_argument( - "--version", - type=str, - default="cosmos-predict2-2b-video2world", - choices=("cosmos-predict2-2b-video2world", "cosmos-predict2-14b-video2world"), - help="Version of Cosmos", - ) - parser.add_argument('--input-image', type=str, default=None, help="Path to the input image") - parser.add_argument('--input-video', type=str, default=None, help="Path to the input video") - parser.add_argument( - "--height", - type=int, - default=704, - help="Height of image to generate (must be multiple of 8)", - ) - parser.add_argument( - "--width", - type=int, - default=1280, - help="Width of image to generate (must be multiple of 8)", - ) - parser.add_argument("--denoising-steps", type=int, default=35, help="Number of denoising steps") - parser.add_argument( - "--guidance-scale", - type=float, - default=7.0, - help="Value of classifier-free guidance scale (must be greater than 1)", - ) - parser.add_argument("--num-frames", type=int, default=93, help="The number of frames in the generated video.") - parser.add_argument("--fps", type=int, default=16, help="The frames per second of the generated video.") - parser.add_argument("--num-videos-per-prompt", type=int, default=1, help="The number of videos to generate per prompt.") - parser.add_argument( - "--max_sequence_length", - type=int, - default=512, - help="Maximum sequence length to use with the prompt.", - ) - parser.add_argument( - "--t5-ws-percentage", - type=int, - default=None, - help="Set runtime weight streaming budget as the percentage of the size of streamable weights for the T5 model. This argument only takes effect when --ws is set. 0 streams the most weights and 100 or None streams no weights. ", - ) - parser.add_argument( - "--transformer-ws-percentage", - type=int, - default=None, - help="Set runtime weight streaming budget as the percentage of the size of streamable weights for the transformer model. This argument only takes effect when --ws is set. 0 streams the most weights and 100 or None streams no weights.", - ) - parser.add_argument( - "--bf16", - action="store_true", - default=True, - help="Use bfloat16 precision by default.", - ) - return parser.parse_args() - - -def process_demo_args(args): - batch_size = args.batch_size - prompt = args.prompt - negative_prompt = args.negative_prompt - # Process input args - if not isinstance(prompt, list): - raise ValueError(f"`prompt` must be of type `str` list, but is {type(prompt)}") - prompt = prompt * batch_size - if not isinstance(negative_prompt, list): - raise ValueError(f"`negative_prompt` must be of type `str` list, but is {type(negative_prompt)}") - negative_prompt = negative_prompt * batch_size - - # process input image and input video - if args.input_image and args.input_video: - raise ValueError("Only one of --input-image or --input-video can be provided") - if args.input_image: - args.input_image = load_image(args.input_image) - elif args.input_video: - args.input_video = load_video(args.input_video) - else: - # load default image - args.input_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/yellow-scrubber.png") - - kwargs_run_demo = { - "prompt": prompt, - "negative_prompt": negative_prompt, - "height": args.height, - "width": args.width, - "batch_count": args.batch_count, - "num_warmup_runs": args.num_warmup_runs, - "use_cuda_graph": args.use_cuda_graph, - "num_frames": args.num_frames, - "fps": args.fps, - "input_image": args.input_image, - "input_video": args.input_video, - "num_videos_per_prompt": args.num_videos_per_prompt, - } - - return kwargs_run_demo - - -if __name__ == "__main__": - print("[I] Initializing Cosmos video2world demo using TensorRT") - args = parse_args() - - # Enforce torch-inference is enabled - if not args.torch_inference: - print("[W] The video2world demo only supports the PyTorch backend. Enabling torch-inference with 'eager' mode.") - args.torch_inference = "eager" - - _, kwargs_load_engine, _ = dd_argparse.process_pipeline_args(args) - kwargs_run_demo = process_demo_args(args) - - # Initialize demo - demo = pipeline_module.CosmosPipeline.FromArgs(args, pipeline_type=pipeline_module.PIPELINE_TYPE.VIDEO2WORLD) - - # Load TensorRT engines and pytorch modules - demo.load_engines( - framework_model_dir=args.framework_model_dir, - **kwargs_load_engine, - ) - - if args.onnx_export_only: - print("[I] ONNX export completed. Exiting...") - demo.teardown() - exit(0) - - # In low-vram mode we allocate the required device memory individually before each model is run. - if demo.low_vram: - demo.device_memory_sizes = demo.get_device_memory_sizes() - else: - _, shared_device_memory = cudart.cudaMalloc(demo.calculate_max_device_memory()) - demo.activate_engines(shared_device_memory) - - demo.load_resources(args.height, args.width, args.batch_size, args.seed) - - # Run inference - videos = demo.run(**kwargs_run_demo) - - demo.teardown() - - # save video - demo.save_video(kwargs_run_demo["prompt"], videos, check_integrity=True) diff --git a/demo/Diffusion/docs/support_matrix.md b/demo/Diffusion/docs/support_matrix.md deleted file mode 100644 index 5d49f29d7..000000000 --- a/demo/Diffusion/docs/support_matrix.md +++ /dev/null @@ -1,33 +0,0 @@ - - -# Supported Diffusion Models - -This demo supports Diffusion models that are popular in the Generative AI community. The table below lists the various configurations we support for each pipeline. - -## Pipeline Support Matrix - -| Pipeline | Version | Task | Supported Precisions | Additional features | Hub | Restrictions | -|------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------|-----------------------------------------------|--------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Stable Diffusion | 1.4 |
  • Text-to-image
  • Image-to-image
| FP16, FP8, INT8 * | N/A | [CompVis/stable-diffusion-v1-4](https://huggingface.co/CompVis/stable-diffusion-v1-4) | | -| Stable Diffusion | dreamshaper-7 |
  • Text-to-image
  • Image-to-image
| FP16 | N/A | [Lykon/dreamshaper-7](https://huggingface.co/Lykon/dreamshaper-7) | -| Stable Diffusion | [XL 1.0-base](../README.md#generate-an-image-with-stable-diffusion-xl-guided-by-a-single-text-prompt) |
  • Text-to-image
  • Image-to-image
| FP16, FP8, INT8 * | LoRA (FP16, BF16, FP8) | [stabilityai/stable-diffusion-xl-base-1.0](https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0) | -| Stable Diffusion | [XL 1.0-refiner](../README.md#generate-an-image-with-stable-diffusion-xl-guided-by-a-single-text-prompt) |
  • Text-to-image
  • Image-to-image
| FP16 | N/A | [stabilityai/stable-diffusion-xl-refiner-1.0](https://huggingface.co/stabilityai/stable-diffusion-xl-refiner-1.0) | -| Stable Diffusion | [XL-Turbo](../README.md#faster-text-to-image-using-sdxl-turbo) |
  • Text-to-image
  • Image-to-image
| FP16 | N/A | [stabilityai/sdxl-turbo](https://huggingface.co/stabilityai/sdxl-turbo) | -| Stable Diffusion | [3](../README.md#generate-an-image-guided-by-a-text-prompt-using-stable-diffusion-3) |
  • Text-to-image
| FP16 | N/A | [stabilityai/stable-diffusion-3-medium](https://huggingface.co/stabilityai/stable-diffusion-3-medium) | -| Stable Diffusion | [3.5-medium](../README.md#generate-an-image-guided-by-a-text-prompt-using-stable-diffusion-3) |
  • Text-to-image
| FP16, BF16 | N/A | [stabilityai/stable-diffusion-3-medium](https://huggingface.co/stabilityai/stable-diffusion-3-medium) | -| Stable Diffusion | [3.5-large](../README.md#generate-an-image-guided-by-a-text-prompt-using-stable-diffusion-3) |
  • Text-to-image
| FP16, BF16, FP8 | N/A | [stabilityai/stable-diffusion-3-large](https://huggingface.co/stabilityai/stable-diffusion-3-large) | -| ControlNet | [1.4](../README.md#generate-an-image-with-controlnet-guided-by-images-and-text-prompts) |
  • Image-to-image
| FP16 | N/A |
  • [lllyasviel/sd-controlnet-canny](https://huggingface.co/lllyasviel/sd-controlnet-canny)
  • [lllyasviel/sd-controlnet-depth](https://huggingface.co/lllyasviel/sd-controlnet-depth)
  • [lllyasviel/sd-controlnet-hed](https://huggingface.co/lllyasviel/sd-controlnet-hed)
  • [lllyasviel/sd-controlnet-mlsd](https://huggingface.co/lllyasviel/sd-controlnet-mlsd)
  • [lllyasviel/sd-controlnet-normal](https://huggingface.co/lllyasviel/sd-controlnet-normal)
  • [lllyasviel/sd-controlnet_openpose](https://huggingface.co/lllyasviel/sd-controlnet-openpose)
  • [lllyasviel/sd-controlnet_scribble](https://huggingface.co/lllyasviel/sd-controlnet-scribble)
  • [lllyasviel/sd-controlnet_seg](https://huggingface.co/lllyasviel/sd-controlnet-seg)
| -| ControlNet | [XL 1.0-base](../README.md#generate-an-image-with-stable-diffusion-xl-guided-by-a-single-text-prompt) |
  • Image-to-image
| FP16, FP8 | N/A | [stabilityai/controlnet-canny-sdxl-1.0](https://huggingface.co/diffusers/controlnet-canny-sdxl-1.0) | -| ControlNet | [3.5-large](../README.md#generate-an-image-with-stable-diffusion-v35-large-with-controlnet-guided-by-an-image-and-a-text-prompt) |
  • Image-to-image
| FP16, BF16, FP8 (canny and depth only) | N/A |
  • [stabilityai/stable-diffusion-3.5-large-controlnet-canny](https://huggingface.co/stabilityai/stable-diffusion-3.5-large-controlnet-canny)
  • [stabilityai/stable-diffusion-3.5-large-controlnet-depth](https://huggingface.co/stabilityai/stable-diffusion-3.5-large-controlnet-depth)
  • [stabilityai/stable-diffusion-3.5-large-controlnet-blur](https://huggingface.co/stabilityai/stable-diffusion-3.5-large-controlnet-blur)
| -| Stable Video Diffusion | [XT-1.1](../README.md#generate-a-video-guided-by-an-initial-image-using-stable-video-diffusion) |
  • Text-to-video
| FP16, FP8 | N/A | [stabilityai/stable-video-diffusion-img2vid-xt-1-1](https://huggingface.co/stabilityai/stable-video-diffusion-img2vid-xt-1-1) | -| Stable Cascade | [N/A](../README.md#generate-an-image-guided-by-a-text-prompt-using-stable-cascade) |
  • Text-to-image
| BF16 | N/A |
  • [stabilityai/stable-cascade-prior](https://huggingface.co/stabilityai/stable-cascade-prior)
  • [stabilityai/stable-cascade](https://huggingface.co/stabilityai/stable-cascade)
| -| Flux | [1-Dev](../README.md#generate-an-image-guided-by-a-text-prompt-using-flux) |
  • Text-to-image
  • Image-to-image
| FP16, BF16, FP8, FP4 * | LoRA (FP16, BF16, FP8) | [black-forest-labs/FLUX.1-dev](https://huggingface.co/black-forest-labs/FLUX.1-dev) | -| Flux | [1-Schnell](../README.md#generate-an-image-guided-by-a-text-prompt-using-flux) |
  • Text-to-image
  • Image-to-image
| FP16, BF16, FP8, FP4 * | LoRA (FP16, BF16, FP8) | [black-forest-labs/FLUX.1-schnell](https://huggingface.co/black-forest-labs/FLUX.1-schnell) | -| Flux | [1-Canny-Dev](../README.md#generate-an-image-guided-by-a-text-prompt-and-a-control-image-using-flux-controlnet) |
  • Image-to-image
| FP16, BF16, FP8, FP4 | N/A | [black-forest-labs/FLUX.1-Canny-dev](https://huggingface.co/black-forest-labs/FLUX.1-Canny-dev) | -| Flux | [1-Depth-Dev](../README.md#generate-an-image-guided-by-a-text-prompt-and-a-control-image-using-flux-controlnet) |
  • Image-to-image
| FP16, BF16, FP8, FP4 | N/A | [black-forest-labs/FLUX.1-Depth-dev](https://huggingface.co/black-forest-labs/FLUX.1-Depth-dev) | -| Flux | [1-Kontext-Dev](../README.md#5-edit-an-image-using-flux-kontext) |
  • Image-to-image
| BF16, FP8, FP4 | N/A | [black-forest-labs/FLUX.1-Kontext-dev](https://huggingface.co/black-forest-labs/FLUX.1-Kontext-dev) | -| Cosmos | [cosmos-predict2-2b-text2image](../README.md#1-generate-an-image-from-a-text-prompt-1), cosmos-predict2-14b-text2image |
  • Text-to-image
| BF16 | N/A |
  • [nvidia/Cosmos-Predict2-2B-Text2Image](https://huggingface.co/nvidia/Cosmos-Predict2-2B-Text2Image)
  • [nvidia/Cosmos-Predict2-14B-Text2Image](https://huggingface.co/nvidia/Cosmos-Predict2-14B-Text2Image) | -| Cosmos | [cosmos-predict2-2b-video2world](../README.md#2-generate-a-video-guided-by-an-initial-video-conditioning-and-a-text-prompt), cosmos-predict2-14b-video2world |
    • Video-to-World
    | BF16 | N/A |
    • [nvidia/Cosmos-Predict2-2B-Video2World](https://huggingface.co/nvidia/Cosmos-Predict2-2B-Video2World)
    • [nvidia/Cosmos-Predict2-14B-Video2World](https://huggingface.co/nvidia/Cosmos-Predict2-14B-Video2World) | -| Wan | [2.2-T2V-A14B](../README.md#generate-a-video-from-a-text-prompt-using-wan) |
      • Text-to-video
      | BF16 | N/A | [wan-ai/wan2.2-t2v-a14b](https://huggingface.co/Wan-AI/Wan2.2-T2V-A14B-Diffusers) | - -*Note: Only the text2image pipelines support FP4/FP8/INT8 quantization. The image2image pipelines don't support quantization. diff --git a/demo/Diffusion/poetry.lock b/demo/Diffusion/poetry.lock deleted file mode 100644 index c5a248a1a..000000000 --- a/demo/Diffusion/poetry.lock +++ /dev/null @@ -1,3494 +0,0 @@ -# This file is automatically @generated by Poetry 2.1.0 and should not be changed by hand. - -[[package]] -name = "accelerate" -version = "1.2.1" -description = "Accelerate" -optional = false -python-versions = ">=3.9.0" -groups = ["main"] -files = [ - {file = "accelerate-1.2.1-py3-none-any.whl", hash = "sha256:be1cbb958cf837e7cdfbde46b812964b1b8ae94c9c7d94d921540beafcee8ddf"}, - {file = "accelerate-1.2.1.tar.gz", hash = "sha256:03e161fc69d495daf2b9b5c8d5b43d06e2145520c04727b5bda56d49f1a43ab5"}, -] - -[package.dependencies] -huggingface-hub = ">=0.21.0" -numpy = ">=1.17,<3.0.0" -packaging = ">=20.0" -psutil = "*" -pyyaml = "*" -safetensors = ">=0.4.3" -torch = ">=1.10.0" - -[package.extras] -deepspeed = ["deepspeed"] -dev = ["bitsandbytes", "black (>=23.1,<24.0)", "datasets", "diffusers", "evaluate", "hf-doc-builder (>=0.3.0)", "parameterized", "pytest (>=7.2.0,<=8.0.0)", "pytest-subtests", "pytest-xdist", "rich", "ruff (>=0.6.4,<0.7.0)", "scikit-learn", "scipy", "timm", "torchdata (>=0.8.0)", "torchpippy (>=0.2.0)", "tqdm", "transformers"] -quality = ["black (>=23.1,<24.0)", "hf-doc-builder (>=0.3.0)", "ruff (>=0.6.4,<0.7.0)"] -rich = ["rich"] -sagemaker = ["sagemaker"] -test-dev = ["bitsandbytes", "datasets", "diffusers", "evaluate", "scikit-learn", "scipy", "timm", "torchdata (>=0.8.0)", "torchpippy (>=0.2.0)", "tqdm", "transformers"] -test-prod = ["parameterized", "pytest (>=7.2.0,<=8.0.0)", "pytest-subtests", "pytest-xdist"] -test-trackers = ["comet-ml", "dvclive", "tensorboard", "wandb"] -testing = ["bitsandbytes", "datasets", "diffusers", "evaluate", "parameterized", "pytest (>=7.2.0,<=8.0.0)", "pytest-subtests", "pytest-xdist", "scikit-learn", "scipy", "timm", "torchdata (>=0.8.0)", "torchpippy (>=0.2.0)", "tqdm", "transformers"] - -[[package]] -name = "anykeystore" -version = "0.2" -description = "A key-value store supporting multiple backends." -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "anykeystore-0.2.tar.gz", hash = "sha256:82ffcd608fea9cfaa903b7731c47a8d36ba346bf49cf98f8dabee83083d08412"}, -] - -[[package]] -name = "apex" -version = "0.9.10dev" -description = "Pyramid toolkit to add Velruse, Flash Messages,CSRF, ReCaptcha and Sessions" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "apex-0.9.10dev.tar.gz", hash = "sha256:48aa6d9e805e661e609161bd52e0d02d89a9a32f32dc29cde6c950df58129119"}, -] - -[package.dependencies] -cryptacular = "*" -pyramid = ">1.1.2" -pyramid_mailer = "*" -requests = "*" -velruse = ">=1.0.3" -wtforms = "*" -wtforms-recaptcha = "*" -"zope.sqlalchemy" = "*" - -[[package]] -name = "certifi" -version = "2025.10.5" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de"}, - {file = "certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.3" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "charset_normalizer-3.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-win32.whl", hash = "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-win32.whl", hash = "sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-win32.whl", hash = "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca"}, - {file = "charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a"}, - {file = "charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["main"] -markers = "platform_system == \"Windows\"" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "colored" -version = "2.3.1" -description = "Simple python library for color and formatting to terminal" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "colored-2.3.1-py3-none-any.whl", hash = "sha256:15d85396d6841f79534bf4668330b5e8686a5e58e730c84ada0e09d335b21fd1"}, - {file = "colored-2.3.1.tar.gz", hash = "sha256:fe6e888e12dc16643daa0b108f785df6d0b48420084b5d0a567de27bb09a14d8"}, -] - -[[package]] -name = "contourpy" -version = "1.3.2" -description = "Python library for calculating contours of 2D quadrilateral grids" -optional = false -python-versions = ">=3.10" -groups = ["main"] -markers = "python_version == \"3.10\"" -files = [ - {file = "contourpy-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba38e3f9f330af820c4b27ceb4b9c7feee5fe0493ea53a8720f4792667465934"}, - {file = "contourpy-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc41ba0714aa2968d1f8674ec97504a8f7e334f48eeacebcaa6256213acb0989"}, - {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9be002b31c558d1ddf1b9b415b162c603405414bacd6932d031c5b5a8b757f0d"}, - {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d2e74acbcba3bfdb6d9d8384cdc4f9260cae86ed9beee8bd5f54fee49a430b9"}, - {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e259bced5549ac64410162adc973c5e2fb77f04df4a439d00b478e57a0e65512"}, - {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad687a04bc802cbe8b9c399c07162a3c35e227e2daccf1668eb1f278cb698631"}, - {file = "contourpy-1.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cdd22595308f53ef2f891040ab2b93d79192513ffccbd7fe19be7aa773a5e09f"}, - {file = "contourpy-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b4f54d6a2defe9f257327b0f243612dd051cc43825587520b1bf74a31e2f6ef2"}, - {file = "contourpy-1.3.2-cp310-cp310-win32.whl", hash = "sha256:f939a054192ddc596e031e50bb13b657ce318cf13d264f095ce9db7dc6ae81c0"}, - {file = "contourpy-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c440093bbc8fc21c637c03bafcbef95ccd963bc6e0514ad887932c18ca2a759a"}, - {file = "contourpy-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a37a2fb93d4df3fc4c0e363ea4d16f83195fc09c891bc8ce072b9d084853445"}, - {file = "contourpy-1.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b7cd50c38f500bbcc9b6a46643a40e0913673f869315d8e70de0438817cb7773"}, - {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6658ccc7251a4433eebd89ed2672c2ed96fba367fd25ca9512aa92a4b46c4f1"}, - {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:70771a461aaeb335df14deb6c97439973d253ae70660ca085eec25241137ef43"}, - {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65a887a6e8c4cd0897507d814b14c54a8c2e2aa4ac9f7686292f9769fcf9a6ab"}, - {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3859783aefa2b8355697f16642695a5b9792e7a46ab86da1118a4a23a51a33d7"}, - {file = "contourpy-1.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eab0f6db315fa4d70f1d8ab514e527f0366ec021ff853d7ed6a2d33605cf4b83"}, - {file = "contourpy-1.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d91a3ccc7fea94ca0acab82ceb77f396d50a1f67412efe4c526f5d20264e6ecd"}, - {file = "contourpy-1.3.2-cp311-cp311-win32.whl", hash = "sha256:1c48188778d4d2f3d48e4643fb15d8608b1d01e4b4d6b0548d9b336c28fc9b6f"}, - {file = "contourpy-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:5ebac872ba09cb8f2131c46b8739a7ff71de28a24c869bcad554477eb089a878"}, - {file = "contourpy-1.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4caf2bcd2969402bf77edc4cb6034c7dd7c0803213b3523f111eb7460a51b8d2"}, - {file = "contourpy-1.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82199cb78276249796419fe36b7386bd8d2cc3f28b3bc19fe2454fe2e26c4c15"}, - {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:106fab697af11456fcba3e352ad50effe493a90f893fca6c2ca5c033820cea92"}, - {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d14f12932a8d620e307f715857107b1d1845cc44fdb5da2bc8e850f5ceba9f87"}, - {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:532fd26e715560721bb0d5fc7610fce279b3699b018600ab999d1be895b09415"}, - {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b383144cf2d2c29f01a1e8170f50dacf0eac02d64139dcd709a8ac4eb3cfe"}, - {file = "contourpy-1.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c49f73e61f1f774650a55d221803b101d966ca0c5a2d6d5e4320ec3997489441"}, - {file = "contourpy-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3d80b2c0300583228ac98d0a927a1ba6a2ba6b8a742463c564f1d419ee5b211e"}, - {file = "contourpy-1.3.2-cp312-cp312-win32.whl", hash = "sha256:90df94c89a91b7362e1142cbee7568f86514412ab8a2c0d0fca72d7e91b62912"}, - {file = "contourpy-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c942a01d9163e2e5cfb05cb66110121b8d07ad438a17f9e766317bcb62abf73"}, - {file = "contourpy-1.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:de39db2604ae755316cb5967728f4bea92685884b1e767b7c24e983ef5f771cb"}, - {file = "contourpy-1.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f9e896f447c5c8618f1edb2bafa9a4030f22a575ec418ad70611450720b5b08"}, - {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71e2bd4a1c4188f5c2b8d274da78faab884b59df20df63c34f74aa1813c4427c"}, - {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de425af81b6cea33101ae95ece1f696af39446db9682a0b56daaa48cfc29f38f"}, - {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:977e98a0e0480d3fe292246417239d2d45435904afd6d7332d8455981c408b85"}, - {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:434f0adf84911c924519d2b08fc10491dd282b20bdd3fa8f60fd816ea0b48841"}, - {file = "contourpy-1.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c66c4906cdbc50e9cba65978823e6e00b45682eb09adbb78c9775b74eb222422"}, - {file = "contourpy-1.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8b7fc0cd78ba2f4695fd0a6ad81a19e7e3ab825c31b577f384aa9d7817dc3bef"}, - {file = "contourpy-1.3.2-cp313-cp313-win32.whl", hash = "sha256:15ce6ab60957ca74cff444fe66d9045c1fd3e92c8936894ebd1f3eef2fff075f"}, - {file = "contourpy-1.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e1578f7eafce927b168752ed7e22646dad6cd9bca673c60bff55889fa236ebf9"}, - {file = "contourpy-1.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0475b1f6604896bc7c53bb070e355e9321e1bc0d381735421a2d2068ec56531f"}, - {file = "contourpy-1.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c85bb486e9be652314bb5b9e2e3b0d1b2e643d5eec4992c0fbe8ac71775da739"}, - {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:745b57db7758f3ffc05a10254edd3182a2a83402a89c00957a8e8a22f5582823"}, - {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:970e9173dbd7eba9b4e01aab19215a48ee5dd3f43cef736eebde064a171f89a5"}, - {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6c4639a9c22230276b7bffb6a850dfc8258a2521305e1faefe804d006b2e532"}, - {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc829960f34ba36aad4302e78eabf3ef16a3a100863f0d4eeddf30e8a485a03b"}, - {file = "contourpy-1.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d32530b534e986374fc19eaa77fcb87e8a99e5431499949b828312bdcd20ac52"}, - {file = "contourpy-1.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e298e7e70cf4eb179cc1077be1c725b5fd131ebc81181bf0c03525c8abc297fd"}, - {file = "contourpy-1.3.2-cp313-cp313t-win32.whl", hash = "sha256:d0e589ae0d55204991450bb5c23f571c64fe43adaa53f93fc902a84c96f52fe1"}, - {file = "contourpy-1.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:78e9253c3de756b3f6a5174d024c4835acd59eb3f8e2ca13e775dbffe1558f69"}, - {file = "contourpy-1.3.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fd93cc7f3139b6dd7aab2f26a90dde0aa9fc264dbf70f6740d498a70b860b82c"}, - {file = "contourpy-1.3.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:107ba8a6a7eec58bb475329e6d3b95deba9440667c4d62b9b6063942b61d7f16"}, - {file = "contourpy-1.3.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ded1706ed0c1049224531b81128efbd5084598f18d8a2d9efae833edbd2b40ad"}, - {file = "contourpy-1.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5f5964cdad279256c084b69c3f412b7801e15356b16efa9d78aa974041903da0"}, - {file = "contourpy-1.3.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49b65a95d642d4efa8f64ba12558fcb83407e58a2dfba9d796d77b63ccfcaff5"}, - {file = "contourpy-1.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8c5acb8dddb0752bf252e01a3035b21443158910ac16a3b0d20e7fed7d534ce5"}, - {file = "contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54"}, -] - -[package.dependencies] -numpy = ">=1.23" - -[package.extras] -bokeh = ["bokeh", "selenium"] -docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.15.0)", "types-Pillow"] -test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] - -[[package]] -name = "contourpy" -version = "1.3.3" -description = "Python library for calculating contours of 2D quadrilateral grids" -optional = false -python-versions = ">=3.11" -groups = ["main"] -markers = "python_version >= \"3.11\"" -files = [ - {file = "contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1"}, - {file = "contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381"}, - {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7"}, - {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1"}, - {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a"}, - {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db"}, - {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620"}, - {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f"}, - {file = "contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff"}, - {file = "contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42"}, - {file = "contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470"}, - {file = "contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb"}, - {file = "contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6"}, - {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7"}, - {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8"}, - {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea"}, - {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1"}, - {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7"}, - {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411"}, - {file = "contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69"}, - {file = "contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b"}, - {file = "contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc"}, - {file = "contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5"}, - {file = "contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1"}, - {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286"}, - {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5"}, - {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67"}, - {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9"}, - {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659"}, - {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7"}, - {file = "contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d"}, - {file = "contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263"}, - {file = "contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9"}, - {file = "contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d"}, - {file = "contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216"}, - {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae"}, - {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20"}, - {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99"}, - {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b"}, - {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a"}, - {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e"}, - {file = "contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3"}, - {file = "contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8"}, - {file = "contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301"}, - {file = "contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a"}, - {file = "contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77"}, - {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5"}, - {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4"}, - {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36"}, - {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3"}, - {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b"}, - {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36"}, - {file = "contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d"}, - {file = "contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd"}, - {file = "contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339"}, - {file = "contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772"}, - {file = "contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77"}, - {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13"}, - {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe"}, - {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f"}, - {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0"}, - {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4"}, - {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f"}, - {file = "contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae"}, - {file = "contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc"}, - {file = "contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b"}, - {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497"}, - {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8"}, - {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e"}, - {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989"}, - {file = "contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77"}, - {file = "contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880"}, -] - -[package.dependencies] -numpy = ">=1.25" - -[package.extras] -bokeh = ["bokeh", "selenium"] -docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.17.0)", "types-Pillow"] -test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] - -[[package]] -name = "controlnet-aux" -version = "0.0.6" -description = "Auxillary models for controlnet" -optional = false -python-versions = ">=3.7.0" -groups = ["main"] -files = [ - {file = "controlnet_aux-0.0.6-py3-none-any.whl", hash = "sha256:8790580486aabfcde4d0ef0595e1a40f83fafad03a8a044eaa61e4a4f74650c5"}, - {file = "controlnet_aux-0.0.6.tar.gz", hash = "sha256:1bec9a4aeff7eacccfaf8b86e744012ecc186e218e386ef21032780766f894fc"}, -] - -[package.dependencies] -einops = "*" -filelock = "*" -huggingface-hub = "*" -importlib-metadata = "*" -numpy = "*" -opencv-python = "*" -Pillow = "*" -scikit-image = "*" -scipy = "*" -timm = "*" -torch = "*" -torchvision = "*" - -[[package]] -name = "cryptacular" -version = "1.6.2" -description = "A password hashing framework with bcrypt and pbkdf2." -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "cryptacular-1.6.2.tar.gz", hash = "sha256:7b529cb2b8a3c7e5be77921bf1ebc653d4d3a8f791375cc6f971b20db2404176"}, -] - -[package.dependencies] -pbkdf2 = "*" -setuptools = "*" - -[package.extras] -test = ["pytest", "pytest-cov"] - -[[package]] -name = "cuda-bindings" -version = "13.0.2" -description = "Python bindings for CUDA" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "cuda_bindings-13.0.2-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:280b5006cd335d119723ac553e031fd04e59f3e298ea1ffecb980572eac45f1e"}, - {file = "cuda_bindings-13.0.2-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:08b647b9cf876ce671baeaed0f0da3e73b542fa7bd35acf596a9e1b363187cca"}, - {file = "cuda_bindings-13.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6a9186b5b680a30fc8787fe94443894e356031e96543bf73151f4d67c94cd507"}, - {file = "cuda_bindings-13.0.2-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ca38804d369a010656e8aba5541debead0e9630c4905b6483c89f3115e21b6e0"}, - {file = "cuda_bindings-13.0.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a82e17e4271a7bdb1117d3c89818f746e71e46a99bbb34a0b45b691d3d36cde"}, - {file = "cuda_bindings-13.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:8e3625b1f3d6cbdf350f389f17f3592ee8116891732ba2fcc6aa6d1a6d9617a1"}, - {file = "cuda_bindings-13.0.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ca14beca5fb12fea80ec21176c6832dff20f4ec213db3bab74f6a865bc045dd"}, - {file = "cuda_bindings-13.0.2-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dbeb48f46d8bb970c6462c1fcb805cf04e481964491d0c39f0ea661de6fff114"}, - {file = "cuda_bindings-13.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:583f726e260724796842e698b06240ffb2cc96452aad41a3c515e94ac00df90f"}, - {file = "cuda_bindings-13.0.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:987619007e27c90a32ab05eb277027a9fb1c7143d314e199cbd3dc5b7ef8875c"}, - {file = "cuda_bindings-13.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6ff47ce0eab493661b15ef8fd766876c98a3c4d3f2544232059f04aad242c4d"}, - {file = "cuda_bindings-13.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:a0b732e538c306fd51f429bc5f7876edd059ac9009adc71e61ea1bb4363da1b0"}, - {file = "cuda_bindings-13.0.2-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48627ac7ab789c8120775d05579d772cca2d82578a08a59d125a54bb60bc0d5c"}, - {file = "cuda_bindings-13.0.2-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4f1fdd784ced356b07f908106e5df2702c830f5cc1fa7edf2c46ba97a7cd8f6"}, - {file = "cuda_bindings-13.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:260dda23f78a2106ecd085ed00874e276f1d91efc49d1dff9071f0fdf865d996"}, - {file = "cuda_bindings-13.0.2-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:54b7424425f51ea9b01145b55eb203f86324e383ec05ee5be9b658523e670188"}, - {file = "cuda_bindings-13.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83d091a8dccf0d770eceaa9c956017b629885a97ad3497db2c3960962863dac3"}, - {file = "cuda_bindings-13.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:732a20408df72d123387a54f6e577eeaa73e166d5ea5244e473010f05a3ec2b2"}, - {file = "cuda_bindings-13.0.2-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:81423974e15c7366d5ed92377cf423da938c63b2e7392c3eff75c0917cea9f12"}, - {file = "cuda_bindings-13.0.2-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6a062f4d373a5bbf639ad03534ef05cf6056bdbb1ebb3b2e9d27684cc55f92b"}, - {file = "cuda_bindings-13.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:44a8e6aee617d292581a2eebbbf62749a855cc9c704b51b9537474d25b80fdfe"}, - {file = "cuda_bindings-13.0.2-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:633bd68fc4687a6d8ab240c4e150008a7e98eab5b8f8e033da3c7460b573f89a"}, - {file = "cuda_bindings-13.0.2-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e027f326f38fdd06212c3bb34c5d4b56bce94d274fa4116e77ca1f02682a7c70"}, - {file = "cuda_bindings-13.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6184fee423134821b423cb69db25853176c602028d9f5582af0b1516a4113d95"}, -] - -[package.dependencies] -cuda-pathfinder = ">=1.1,<2.0" - -[package.extras] -all = ["cuda-toolkit[cufile] (==13.*) ; sys_platform == \"linux\"", "cuda-toolkit[nvjitlink,nvrtc,nvvm] (==13.*)"] - -[[package]] -name = "cuda-pathfinder" -version = "1.3.0" -description = "Pathfinder for CUDA components" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "cuda_pathfinder-1.3.0-py3-none-any.whl", hash = "sha256:2e904a408ab4ebfba5b3ee67ecd15383487ffe109fc6e1f2e2ea61577e4519be"}, -] - -[package.extras] -test = ["pytest (>=6.2.4)"] -test-nvidia-wheels-cu12 = ["cuda-toolkit[cccl,cublas,cudart,cufft,curand,cusolver,cusparse,npp,nvcc,nvfatbin,nvjitlink,nvjpeg,nvrtc] (==12.*)", "cuda-toolkit[cufile] (==12.*) ; sys_platform != \"win32\"", "nvidia-cudss-cu12", "nvidia-cufftmp-cu12 ; sys_platform != \"win32\"", "nvidia-libmathdx-cu12", "nvidia-nccl-cu12 ; sys_platform != \"win32\"", "nvidia-nvshmem-cu12 ; sys_platform != \"win32\""] -test-nvidia-wheels-cu13 = ["cuda-toolkit[cccl,cublas,cudart,cufft,curand,cusolver,cusparse,npp,nvcc,nvfatbin,nvjitlink,nvjpeg,nvrtc,nvvm] (==13.*)", "cuda-toolkit[cufile] (==13.*) ; sys_platform != \"win32\"", "nvidia-nccl-cu13 ; sys_platform != \"win32\"", "nvidia-nvshmem-cu13 ; sys_platform != \"win32\""] -test-nvidia-wheels-host = ["nvpl-fft ; platform_system == \"Linux\" and platform_machine == \"aarch64\""] - -[[package]] -name = "cuda-python" -version = "13.0.2" -description = "CUDA Python: Performance meets Productivity" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "cuda_python-13.0.2-py3-none-any.whl", hash = "sha256:5ad711c64236f4cf62ba94806e47042121ceb4f4c3be2600a84b0ab6b0f698a0"}, -] - -[package.dependencies] -cuda-bindings = ">=13.0.2,<13.1.0" -cuda-pathfinder = ">=1.1,<2.0" - -[package.extras] -all = ["cuda-bindings[all] (>=13.0.2,<13.1.0)"] - -[[package]] -name = "cycler" -version = "0.12.1" -description = "Composable style cycles" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, - {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, -] - -[package.extras] -docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] -tests = ["pytest", "pytest-cov", "pytest-xdist"] - -[[package]] -name = "einops" -version = "0.8.1" -description = "A new flavour of deep learning operations" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "einops-0.8.1-py3-none-any.whl", hash = "sha256:919387eb55330f5757c6bea9165c5ff5cfe63a642682ea788a6d472576d81737"}, - {file = "einops-0.8.1.tar.gz", hash = "sha256:de5d960a7a761225532e0f1959e5315ebeafc0cd43394732f103ca44b9837e84"}, -] - -[[package]] -name = "filelock" -version = "3.20.0" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.10" -groups = ["main"] -files = [ - {file = "filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2"}, - {file = "filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4"}, -] - -[[package]] -name = "fonttools" -version = "4.60.1" -description = "Tools to manipulate font files" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "fonttools-4.60.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9a52f254ce051e196b8fe2af4634c2d2f02c981756c6464dc192f1b6050b4e28"}, - {file = "fonttools-4.60.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7420a2696a44650120cdd269a5d2e56a477e2bfa9d95e86229059beb1c19e15"}, - {file = "fonttools-4.60.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee0c0b3b35b34f782afc673d503167157094a16f442ace7c6c5e0ca80b08f50c"}, - {file = "fonttools-4.60.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:282dafa55f9659e8999110bd8ed422ebe1c8aecd0dc396550b038e6c9a08b8ea"}, - {file = "fonttools-4.60.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4ba4bd646e86de16160f0fb72e31c3b9b7d0721c3e5b26b9fa2fc931dfdb2652"}, - {file = "fonttools-4.60.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0b0835ed15dd5b40d726bb61c846a688f5b4ce2208ec68779bc81860adb5851a"}, - {file = "fonttools-4.60.1-cp310-cp310-win32.whl", hash = "sha256:1525796c3ffe27bb6268ed2a1bb0dcf214d561dfaf04728abf01489eb5339dce"}, - {file = "fonttools-4.60.1-cp310-cp310-win_amd64.whl", hash = "sha256:268ecda8ca6cb5c4f044b1fb9b3b376e8cd1b361cef275082429dc4174907038"}, - {file = "fonttools-4.60.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7b4c32e232a71f63a5d00259ca3d88345ce2a43295bb049d21061f338124246f"}, - {file = "fonttools-4.60.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3630e86c484263eaac71d117085d509cbcf7b18f677906824e4bace598fb70d2"}, - {file = "fonttools-4.60.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5c1015318e4fec75dd4943ad5f6a206d9727adf97410d58b7e32ab644a807914"}, - {file = "fonttools-4.60.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e6c58beb17380f7c2ea181ea11e7db8c0ceb474c9dd45f48e71e2cb577d146a1"}, - {file = "fonttools-4.60.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec3681a0cb34c255d76dd9d865a55f260164adb9fa02628415cdc2d43ee2c05d"}, - {file = "fonttools-4.60.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f4b5c37a5f40e4d733d3bbaaef082149bee5a5ea3156a785ff64d949bd1353fa"}, - {file = "fonttools-4.60.1-cp311-cp311-win32.whl", hash = "sha256:398447f3d8c0c786cbf1209711e79080a40761eb44b27cdafffb48f52bcec258"}, - {file = "fonttools-4.60.1-cp311-cp311-win_amd64.whl", hash = "sha256:d066ea419f719ed87bc2c99a4a4bfd77c2e5949cb724588b9dd58f3fd90b92bf"}, - {file = "fonttools-4.60.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7b0c6d57ab00dae9529f3faf187f2254ea0aa1e04215cf2f1a8ec277c96661bc"}, - {file = "fonttools-4.60.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:839565cbf14645952d933853e8ade66a463684ed6ed6c9345d0faf1f0e868877"}, - {file = "fonttools-4.60.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8177ec9676ea6e1793c8a084a90b65a9f778771998eb919d05db6d4b1c0b114c"}, - {file = "fonttools-4.60.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:996a4d1834524adbb423385d5a629b868ef9d774670856c63c9a0408a3063401"}, - {file = "fonttools-4.60.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a46b2f450bc79e06ef3b6394f0c68660529ed51692606ad7f953fc2e448bc903"}, - {file = "fonttools-4.60.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ec722ee589e89a89f5b7574f5c45604030aa6ae24cb2c751e2707193b466fed"}, - {file = "fonttools-4.60.1-cp312-cp312-win32.whl", hash = "sha256:b2cf105cee600d2de04ca3cfa1f74f1127f8455b71dbad02b9da6ec266e116d6"}, - {file = "fonttools-4.60.1-cp312-cp312-win_amd64.whl", hash = "sha256:992775c9fbe2cf794786fa0ffca7f09f564ba3499b8fe9f2f80bd7197db60383"}, - {file = "fonttools-4.60.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6f68576bb4bbf6060c7ab047b1574a1ebe5c50a17de62830079967b211059ebb"}, - {file = "fonttools-4.60.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:eedacb5c5d22b7097482fa834bda0dafa3d914a4e829ec83cdea2a01f8c813c4"}, - {file = "fonttools-4.60.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b33a7884fabd72bdf5f910d0cf46be50dce86a0362a65cfc746a4168c67eb96c"}, - {file = "fonttools-4.60.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2409d5fb7b55fd70f715e6d34e7a6e4f7511b8ad29a49d6df225ee76da76dd77"}, - {file = "fonttools-4.60.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c8651e0d4b3bdeda6602b85fdc2abbefc1b41e573ecb37b6779c4ca50753a199"}, - {file = "fonttools-4.60.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:145daa14bf24824b677b9357c5e44fd8895c2a8f53596e1b9ea3496081dc692c"}, - {file = "fonttools-4.60.1-cp313-cp313-win32.whl", hash = "sha256:2299df884c11162617a66b7c316957d74a18e3758c0274762d2cc87df7bc0272"}, - {file = "fonttools-4.60.1-cp313-cp313-win_amd64.whl", hash = "sha256:a3db56f153bd4c5c2b619ab02c5db5192e222150ce5a1bc10f16164714bc39ac"}, - {file = "fonttools-4.60.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:a884aef09d45ba1206712c7dbda5829562d3fea7726935d3289d343232ecb0d3"}, - {file = "fonttools-4.60.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8a44788d9d91df72d1a5eac49b31aeb887a5f4aab761b4cffc4196c74907ea85"}, - {file = "fonttools-4.60.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e852d9dda9f93ad3651ae1e3bb770eac544ec93c3807888798eccddf84596537"}, - {file = "fonttools-4.60.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:154cb6ee417e417bf5f7c42fe25858c9140c26f647c7347c06f0cc2d47eff003"}, - {file = "fonttools-4.60.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5664fd1a9ea7f244487ac8f10340c4e37664675e8667d6fee420766e0fb3cf08"}, - {file = "fonttools-4.60.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:583b7f8e3c49486e4d489ad1deacfb8d5be54a8ef34d6df824f6a171f8511d99"}, - {file = "fonttools-4.60.1-cp314-cp314-win32.whl", hash = "sha256:66929e2ea2810c6533a5184f938502cfdaea4bc3efb7130d8cc02e1c1b4108d6"}, - {file = "fonttools-4.60.1-cp314-cp314-win_amd64.whl", hash = "sha256:f3d5be054c461d6a2268831f04091dc82753176f6ea06dc6047a5e168265a987"}, - {file = "fonttools-4.60.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:b6379e7546ba4ae4b18f8ae2b9bc5960936007a1c0e30b342f662577e8bc3299"}, - {file = "fonttools-4.60.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9d0ced62b59e0430b3690dbc5373df1c2aa7585e9a8ce38eff87f0fd993c5b01"}, - {file = "fonttools-4.60.1-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:875cb7764708b3132637f6c5fb385b16eeba0f7ac9fa45a69d35e09b47045801"}, - {file = "fonttools-4.60.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a184b2ea57b13680ab6d5fbde99ccef152c95c06746cb7718c583abd8f945ccc"}, - {file = "fonttools-4.60.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:026290e4ec76583881763fac284aca67365e0be9f13a7fb137257096114cb3bc"}, - {file = "fonttools-4.60.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f0e8817c7d1a0c2eedebf57ef9a9896f3ea23324769a9a2061a80fe8852705ed"}, - {file = "fonttools-4.60.1-cp314-cp314t-win32.whl", hash = "sha256:1410155d0e764a4615774e5c2c6fc516259fe3eca5882f034eb9bfdbee056259"}, - {file = "fonttools-4.60.1-cp314-cp314t-win_amd64.whl", hash = "sha256:022beaea4b73a70295b688f817ddc24ed3e3418b5036ffcd5658141184ef0d0c"}, - {file = "fonttools-4.60.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:122e1a8ada290423c493491d002f622b1992b1ab0b488c68e31c413390dc7eb2"}, - {file = "fonttools-4.60.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a140761c4ff63d0cb9256ac752f230460ee225ccef4ad8f68affc723c88e2036"}, - {file = "fonttools-4.60.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0eae96373e4b7c9e45d099d7a523444e3554360927225c1cdae221a58a45b856"}, - {file = "fonttools-4.60.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:596ecaca36367027d525b3b426d8a8208169d09edcf8c7506aceb3a38bfb55c7"}, - {file = "fonttools-4.60.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2ee06fc57512144d8b0445194c2da9f190f61ad51e230f14836286470c99f854"}, - {file = "fonttools-4.60.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b42d86938e8dda1cd9a1a87a6d82f1818eaf933348429653559a458d027446da"}, - {file = "fonttools-4.60.1-cp39-cp39-win32.whl", hash = "sha256:8b4eb332f9501cb1cd3d4d099374a1e1306783ff95489a1026bde9eb02ccc34a"}, - {file = "fonttools-4.60.1-cp39-cp39-win_amd64.whl", hash = "sha256:7473a8ed9ed09aeaa191301244a5a9dbe46fe0bf54f9d6cd21d83044c3321217"}, - {file = "fonttools-4.60.1-py3-none-any.whl", hash = "sha256:906306ac7afe2156fcf0042173d6ebbb05416af70f6b370967b47f8f00103bbb"}, - {file = "fonttools-4.60.1.tar.gz", hash = "sha256:ef00af0439ebfee806b25f24c8f92109157ff3fac5731dc7867957812e87b8d9"}, -] - -[package.extras] -all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0) ; python_version <= \"3.12\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] -graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""] -lxml = ["lxml (>=4.0)"] -pathops = ["skia-pathops (>=0.5.0)"] -plot = ["matplotlib"] -repacker = ["uharfbuzz (>=0.23.0)"] -symfont = ["sympy"] -type1 = ["xattr ; sys_platform == \"darwin\""] -unicode = ["unicodedata2 (>=15.1.0) ; python_version <= \"3.12\""] -woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"] - -[[package]] -name = "fsspec" -version = "2025.9.0" -description = "File-system specification" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "fsspec-2025.9.0-py3-none-any.whl", hash = "sha256:530dc2a2af60a414a832059574df4a6e10cce927f6f4a78209390fe38955cfb7"}, - {file = "fsspec-2025.9.0.tar.gz", hash = "sha256:19fd429483d25d28b65ec68f9f4adc16c17ea2c7c7bf54ec61360d478fb19c19"}, -] - -[package.extras] -abfs = ["adlfs"] -adl = ["adlfs"] -arrow = ["pyarrow (>=1)"] -dask = ["dask", "distributed"] -dev = ["pre-commit", "ruff (>=0.5)"] -doc = ["numpydoc", "sphinx", "sphinx-design", "sphinx-rtd-theme", "yarl"] -dropbox = ["dropbox", "dropboxdrivefs", "requests"] -full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] -fuse = ["fusepy"] -gcs = ["gcsfs"] -git = ["pygit2"] -github = ["requests"] -gs = ["gcsfs"] -gui = ["panel"] -hdfs = ["pyarrow (>=1)"] -http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)"] -libarchive = ["libarchive-c"] -oci = ["ocifs"] -s3 = ["s3fs"] -sftp = ["paramiko"] -smb = ["smbprotocol"] -ssh = ["paramiko"] -test = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "numpy", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "requests"] -test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask[dataframe,test]", "moto[server] (>4,<5)", "pytest-timeout", "xarray"] -test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard ; python_version < \"3.14\""] -tqdm = ["tqdm"] - -[[package]] -name = "ftfy" -version = "6.3.1" -description = "Fixes mojibake and other problems with Unicode, after the fact" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "ftfy-6.3.1-py3-none-any.whl", hash = "sha256:7c70eb532015cd2f9adb53f101fb6c7945988d023a085d127d1573dc49dd0083"}, - {file = "ftfy-6.3.1.tar.gz", hash = "sha256:9b3c3d90f84fb267fe64d375a07b7f8912d817cf86009ae134aa03e1819506ec"}, -] - -[package.dependencies] -wcwidth = "*" - -[[package]] -name = "greenlet" -version = "3.2.4" -description = "Lightweight in-process concurrent programming" -optional = false -python-versions = ">=3.9" -groups = ["main"] -markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\"" -files = [ - {file = "greenlet-3.2.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f10fd42b5ee276335863712fa3da6608e93f70629c631bf77145021600abc23c"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c8c9e331e58180d0d83c5b7999255721b725913ff6bc6cf39fa2a45841a4fd4b"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58b97143c9cc7b86fc458f215bd0932f1757ce649e05b640fea2e79b54cedb31"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d"}, - {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5"}, - {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f"}, - {file = "greenlet-3.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c"}, - {file = "greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8"}, - {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52"}, - {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa"}, - {file = "greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9"}, - {file = "greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0"}, - {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0"}, - {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f"}, - {file = "greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02"}, - {file = "greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671"}, - {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b"}, - {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae"}, - {file = "greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b"}, - {file = "greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337"}, - {file = "greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01"}, - {file = "greenlet-3.2.4-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:b6a7c19cf0d2742d0809a4c05975db036fdff50cd294a93632d6a310bf9ac02c"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:27890167f55d2387576d1f41d9487ef171849ea0359ce1510ca6e06c8bece11d"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:18d9260df2b5fbf41ae5139e1be4e796d99655f023a636cd0e11e6406cca7d58"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:671df96c1f23c4a0d4077a325483c1503c96a1b7d9db26592ae770daa41233d4"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:16458c245a38991aa19676900d48bd1a6f2ce3e16595051a4db9d012154e8433"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9913f1a30e4526f432991f89ae263459b1c64d1608c0d22a5c79c287b3c70df"}, - {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b90654e092f928f110e0007f572007c9727b5265f7632c2fa7415b4689351594"}, - {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:81701fd84f26330f0d5f4944d4e92e61afe6319dcd9775e39396e39d7c3e5f98"}, - {file = "greenlet-3.2.4-cp39-cp39-win32.whl", hash = "sha256:65458b409c1ed459ea899e939f0e1cdb14f58dbc803f2f93c5eab5694d32671b"}, - {file = "greenlet-3.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:d2e685ade4dafd447ede19c31277a224a239a0a1a4eca4e6390efedf20260cfb"}, - {file = "greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d"}, -] - -[package.extras] -docs = ["Sphinx", "furo"] -test = ["objgraph", "psutil", "setuptools"] - -[[package]] -name = "hf-xet" -version = "1.1.10" -description = "Fast transfer of large files with the Hugging Face Hub." -optional = false -python-versions = ">=3.8" -groups = ["main"] -markers = "platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"arm64\" or platform_machine == \"aarch64\"" -files = [ - {file = "hf_xet-1.1.10-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:686083aca1a6669bc85c21c0563551cbcdaa5cf7876a91f3d074a030b577231d"}, - {file = "hf_xet-1.1.10-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:71081925383b66b24eedff3013f8e6bbd41215c3338be4b94ba75fd75b21513b"}, - {file = "hf_xet-1.1.10-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6bceb6361c80c1cc42b5a7b4e3efd90e64630bcf11224dcac50ef30a47e435"}, - {file = "hf_xet-1.1.10-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eae7c1fc8a664e54753ffc235e11427ca61f4b0477d757cc4eb9ae374b69f09c"}, - {file = "hf_xet-1.1.10-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0a0005fd08f002180f7a12d4e13b22be277725bc23ed0529f8add5c7a6309c06"}, - {file = "hf_xet-1.1.10-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f900481cf6e362a6c549c61ff77468bd59d6dd082f3170a36acfef2eb6a6793f"}, - {file = "hf_xet-1.1.10-cp37-abi3-win_amd64.whl", hash = "sha256:5f54b19cc347c13235ae7ee98b330c26dd65ef1df47e5316ffb1e87713ca7045"}, - {file = "hf_xet-1.1.10.tar.gz", hash = "sha256:408aef343800a2102374a883f283ff29068055c111f003ff840733d3b715bb97"}, -] - -[package.extras] -tests = ["pytest"] - -[[package]] -name = "huggingface-hub" -version = "0.35.3" -description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" -optional = false -python-versions = ">=3.8.0" -groups = ["main"] -files = [ - {file = "huggingface_hub-0.35.3-py3-none-any.whl", hash = "sha256:0e3a01829c19d86d03793e4577816fe3bdfc1602ac62c7fb220d593d351224ba"}, - {file = "huggingface_hub-0.35.3.tar.gz", hash = "sha256:350932eaa5cc6a4747efae85126ee220e4ef1b54e29d31c3b45c5612ddf0b32a"}, -] - -[package.dependencies] -filelock = "*" -fsspec = ">=2023.5.0" -hf-xet = {version = ">=1.1.3,<2.0.0", markers = "platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"arm64\" or platform_machine == \"aarch64\""} -packaging = ">=20.9" -pyyaml = ">=5.1" -requests = "*" -tqdm = ">=4.42.1" -typing-extensions = ">=3.7.4.3" - -[package.extras] -all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "authlib (>=1.3.2)", "fastapi", "gradio (>=4.0.0)", "httpx", "itsdangerous", "jedi", "libcst (>=1.4.0)", "mypy (==1.15.0) ; python_version >= \"3.9\"", "mypy (>=1.14.1,<1.15.0) ; python_version == \"3.8\"", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures (<16.0)", "pytest-vcr", "pytest-xdist", "ruff (>=0.9.0)", "soundfile", "ty", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] -cli = ["InquirerPy (==0.3.4)"] -dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "authlib (>=1.3.2)", "fastapi", "gradio (>=4.0.0)", "httpx", "itsdangerous", "jedi", "libcst (>=1.4.0)", "mypy (==1.15.0) ; python_version >= \"3.9\"", "mypy (>=1.14.1,<1.15.0) ; python_version == \"3.8\"", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures (<16.0)", "pytest-vcr", "pytest-xdist", "ruff (>=0.9.0)", "soundfile", "ty", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] -fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"] -hf-transfer = ["hf-transfer (>=0.1.4)"] -hf-xet = ["hf-xet (>=1.1.2,<2.0.0)"] -inference = ["aiohttp"] -mcp = ["aiohttp", "mcp (>=1.8.0)", "typer"] -oauth = ["authlib (>=1.3.2)", "fastapi", "httpx", "itsdangerous"] -quality = ["libcst (>=1.4.0)", "mypy (==1.15.0) ; python_version >= \"3.9\"", "mypy (>=1.14.1,<1.15.0) ; python_version == \"3.8\"", "ruff (>=0.9.0)", "ty"] -tensorflow = ["graphviz", "pydot", "tensorflow"] -tensorflow-testing = ["keras (<3.0)", "tensorflow"] -testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "authlib (>=1.3.2)", "fastapi", "gradio (>=4.0.0)", "httpx", "itsdangerous", "jedi", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures (<16.0)", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"] -torch = ["safetensors[torch]", "torch"] -typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"] - -[[package]] -name = "hupper" -version = "1.12.1" -description = "Integrated process monitor for developing and reloading daemons." -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "hupper-1.12.1-py3-none-any.whl", hash = "sha256:e872b959f09d90be5fb615bd2e62de89a0b57efc037bdf9637fb09cdf8552b19"}, - {file = "hupper-1.12.1.tar.gz", hash = "sha256:06bf54170ff4ecf4c84ad5f188dee3901173ab449c2608ad05b9bfd6b13e32eb"}, -] - -[package.extras] -docs = ["Sphinx", "pylons-sphinx-themes", "setuptools", "watchdog"] -testing = ["mock", "pytest", "pytest-cov", "watchdog"] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -groups = ["main"] -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "imageio" -version = "2.37.0" -description = "Library for reading and writing a wide range of image, video, scientific, and volumetric data formats." -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "imageio-2.37.0-py3-none-any.whl", hash = "sha256:11efa15b87bc7871b61590326b2d635439acc321cf7f8ce996f812543ce10eed"}, - {file = "imageio-2.37.0.tar.gz", hash = "sha256:71b57b3669666272c818497aebba2b4c5f20d5b37c81720e5e1a56d59c492996"}, -] - -[package.dependencies] -numpy = "*" -pillow = ">=8.3.2" - -[package.extras] -all-plugins = ["astropy", "av", "imageio-ffmpeg", "numpy (>2)", "pillow-heif", "psutil", "rawpy", "tifffile"] -all-plugins-pypy = ["av", "imageio-ffmpeg", "pillow-heif", "psutil", "tifffile"] -build = ["wheel"] -dev = ["black", "flake8", "fsspec[github]", "pytest", "pytest-cov"] -docs = ["numpydoc", "pydata-sphinx-theme", "sphinx (<6)"] -ffmpeg = ["imageio-ffmpeg", "psutil"] -fits = ["astropy"] -full = ["astropy", "av", "black", "flake8", "fsspec[github]", "gdal", "imageio-ffmpeg", "itk", "numpy (>2)", "numpydoc", "pillow-heif", "psutil", "pydata-sphinx-theme", "pytest", "pytest-cov", "rawpy", "sphinx (<6)", "tifffile", "wheel"] -gdal = ["gdal"] -itk = ["itk"] -linting = ["black", "flake8"] -pillow-heif = ["pillow-heif"] -pyav = ["av"] -rawpy = ["numpy (>2)", "rawpy"] -test = ["fsspec[github]", "pytest", "pytest-cov"] -tifffile = ["tifffile"] - -[[package]] -name = "imageio-ffmpeg" -version = "0.6.0" -description = "FFMPEG wrapper for Python" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "imageio_ffmpeg-0.6.0-py3-none-macosx_10_9_intel.macosx_10_9_x86_64.whl", hash = "sha256:9d2baaf867088508d4a3458e61eeb30e945c4ad8016025545f66c4b5aaef0a61"}, - {file = "imageio_ffmpeg-0.6.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b1ae3173414b5fc5f538a726c4e48ea97edc0d2cdc11f103afee655c463fa742"}, - {file = "imageio_ffmpeg-0.6.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:1d47bebd83d2c5fc770720d211855f208af8a596c82d17730aa51e815cdee6dc"}, - {file = "imageio_ffmpeg-0.6.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c7e46fcec401dd990405049d2e2f475e2b397779df2519b544b8aab515195282"}, - {file = "imageio_ffmpeg-0.6.0-py3-none-win32.whl", hash = "sha256:196faa79366b4a82f95c0f4053191d2013f4714a715780f0ad2a68ff37483cc2"}, - {file = "imageio_ffmpeg-0.6.0-py3-none-win_amd64.whl", hash = "sha256:02fa47c83703c37df6bfe4896aab339013f62bf02c5ebf2dce6da56af04ffc0a"}, - {file = "imageio_ffmpeg-0.6.0.tar.gz", hash = "sha256:e2556bed8e005564a9f925bb7afa4002d82770d6b08825078b7697ab88ba1755"}, -] - -[[package]] -name = "importlib-metadata" -version = "8.7.0" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"}, - {file = "importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000"}, -] - -[package.dependencies] -zipp = ">=3.20" - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -perf = ["ipython"] -test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] -type = ["pytest-mypy"] - -[[package]] -name = "jinja2" -version = "3.1.6" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, - {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "kiwisolver" -version = "1.4.9" -description = "A fast implementation of the Cassowary constraint solver" -optional = false -python-versions = ">=3.10" -groups = ["main"] -files = [ - {file = "kiwisolver-1.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b4b4d74bda2b8ebf4da5bd42af11d02d04428b2c32846e4c2c93219df8a7987b"}, - {file = "kiwisolver-1.4.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fb3b8132019ea572f4611d770991000d7f58127560c4889729248eb5852a102f"}, - {file = "kiwisolver-1.4.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84fd60810829c27ae375114cd379da1fa65e6918e1da405f356a775d49a62bcf"}, - {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b78efa4c6e804ecdf727e580dbb9cba85624d2e1c6b5cb059c66290063bd99a9"}, - {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4efec7bcf21671db6a3294ff301d2fc861c31faa3c8740d1a94689234d1b415"}, - {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:90f47e70293fc3688b71271100a1a5453aa9944a81d27ff779c108372cf5567b"}, - {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fdca1def57a2e88ef339de1737a1449d6dbf5fab184c54a1fca01d541317154"}, - {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9cf554f21be770f5111a1690d42313e140355e687e05cf82cb23d0a721a64a48"}, - {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fc1795ac5cd0510207482c3d1d3ed781143383b8cfd36f5c645f3897ce066220"}, - {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ccd09f20ccdbbd341b21a67ab50a119b64a403b09288c27481575105283c1586"}, - {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:540c7c72324d864406a009d72f5d6856f49693db95d1fbb46cf86febef873634"}, - {file = "kiwisolver-1.4.9-cp310-cp310-win_amd64.whl", hash = "sha256:ede8c6d533bc6601a47ad4046080d36b8fc99f81e6f1c17b0ac3c2dc91ac7611"}, - {file = "kiwisolver-1.4.9-cp310-cp310-win_arm64.whl", hash = "sha256:7b4da0d01ac866a57dd61ac258c5607b4cd677f63abaec7b148354d2b2cdd536"}, - {file = "kiwisolver-1.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb14a5da6dc7642b0f3a18f13654847cd8b7a2550e2645a5bda677862b03ba16"}, - {file = "kiwisolver-1.4.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39a219e1c81ae3b103643d2aedb90f1ef22650deb266ff12a19e7773f3e5f089"}, - {file = "kiwisolver-1.4.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2405a7d98604b87f3fc28b1716783534b1b4b8510d8142adca34ee0bc3c87543"}, - {file = "kiwisolver-1.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dc1ae486f9abcef254b5618dfb4113dd49f94c68e3e027d03cf0143f3f772b61"}, - {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a1f570ce4d62d718dce3f179ee78dac3b545ac16c0c04bb363b7607a949c0d1"}, - {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb27e7b78d716c591e88e0a09a2139c6577865d7f2e152488c2cc6257f460872"}, - {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:15163165efc2f627eb9687ea5f3a28137217d217ac4024893d753f46bce9de26"}, - {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bdee92c56a71d2b24c33a7d4c2856bd6419d017e08caa7802d2963870e315028"}, - {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:412f287c55a6f54b0650bd9b6dce5aceddb95864a1a90c87af16979d37c89771"}, - {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2c93f00dcba2eea70af2be5f11a830a742fe6b579a1d4e00f47760ef13be247a"}, - {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f117e1a089d9411663a3207ba874f31be9ac8eaa5b533787024dc07aeb74f464"}, - {file = "kiwisolver-1.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:be6a04e6c79819c9a8c2373317d19a96048e5a3f90bec587787e86a1153883c2"}, - {file = "kiwisolver-1.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:0ae37737256ba2de764ddc12aed4956460277f00c4996d51a197e72f62f5eec7"}, - {file = "kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999"}, - {file = "kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2"}, - {file = "kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14"}, - {file = "kiwisolver-1.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f6008a4919fdbc0b0097089f67a1eb55d950ed7e90ce2cc3e640abadd2757a04"}, - {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67bb8b474b4181770f926f7b7d2f8c0248cbcb78b660fdd41a47054b28d2a752"}, - {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2327a4a30d3ee07d2fbe2e7933e8a37c591663b96ce42a00bc67461a87d7df77"}, - {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a08b491ec91b1d5053ac177afe5290adacf1f0f6307d771ccac5de30592d198"}, - {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8fc5c867c22b828001b6a38d2eaeb88160bf5783c6cb4a5e440efc981ce286d"}, - {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3b3115b2581ea35bb6d1f24a4c90af37e5d9b49dcff267eeed14c3893c5b86ab"}, - {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858e4c22fb075920b96a291928cb7dea5644e94c0ee4fcd5af7e865655e4ccf2"}, - {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed0fecd28cc62c54b262e3736f8bb2512d8dcfdc2bcf08be5f47f96bf405b145"}, - {file = "kiwisolver-1.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:f68208a520c3d86ea51acf688a3e3002615a7f0238002cccc17affecc86a8a54"}, - {file = "kiwisolver-1.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:2c1a4f57df73965f3f14df20b80ee29e6a7930a57d2d9e8491a25f676e197c60"}, - {file = "kiwisolver-1.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5d0432ccf1c7ab14f9949eec60c5d1f924f17c037e9f8b33352fa05799359b8"}, - {file = "kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2"}, - {file = "kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1a12cf6398e8a0a001a059747a1cbf24705e18fe413bc22de7b3d15c67cffe3f"}, - {file = "kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098"}, - {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5656aa670507437af0207645273ccdfee4f14bacd7f7c67a4306d0dcaeaf6eed"}, - {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bfc08add558155345129c7803b3671cf195e6a56e7a12f3dde7c57d9b417f525"}, - {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:40092754720b174e6ccf9e845d0d8c7d8e12c3d71e7fc35f55f3813e96376f78"}, - {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:497d05f29a1300d14e02e6441cf0f5ee81c1ff5a304b0d9fb77423974684e08b"}, - {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdd1a81a1860476eb41ac4bc1e07b3f07259e6d55bbf739b79c8aaedcf512799"}, - {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e6b93f13371d341afee3be9f7c5964e3fe61d5fa30f6a30eb49856935dfe4fc3"}, - {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d75aa530ccfaa593da12834b86a0724f58bff12706659baa9227c2ccaa06264c"}, - {file = "kiwisolver-1.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:dd0a578400839256df88c16abddf9ba14813ec5f21362e1fe65022e00c883d4d"}, - {file = "kiwisolver-1.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:d4188e73af84ca82468f09cadc5ac4db578109e52acb4518d8154698d3a87ca2"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5a0f2724dfd4e3b3ac5a82436a8e6fd16baa7d507117e4279b660fe8ca38a3a1"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1b11d6a633e4ed84fc0ddafd4ebfd8ea49b3f25082c04ad12b8315c11d504dc1"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61874cdb0a36016354853593cffc38e56fc9ca5aa97d2c05d3dcf6922cd55a11"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:60c439763a969a6af93b4881db0eed8fadf93ee98e18cbc35bc8da868d0c4f0c"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92a2f997387a1b79a75e7803aa7ded2cfbe2823852ccf1ba3bcf613b62ae3197"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31d512c812daea6d8b3be3b2bfcbeb091dbb09177706569bcfc6240dcf8b41c"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:52a15b0f35dad39862d376df10c5230155243a2c1a436e39eb55623ccbd68185"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a30fd6fdef1430fd9e1ba7b3398b5ee4e2887783917a687d86ba69985fb08748"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cc9617b46837c6468197b5945e196ee9ca43057bb7d9d1ae688101e4e1dddf64"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:0ab74e19f6a2b027ea4f845a78827969af45ce790e6cb3e1ebab71bdf9f215ff"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dba5ee5d3981160c28d5490f0d1b7ed730c22470ff7f6cc26cfcfaacb9896a07"}, - {file = "kiwisolver-1.4.9-cp313-cp313t-win_arm64.whl", hash = "sha256:0749fd8f4218ad2e851e11cc4dc05c7cbc0cbc4267bdfdb31782e65aace4ee9c"}, - {file = "kiwisolver-1.4.9-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9928fe1eb816d11ae170885a74d074f57af3a0d65777ca47e9aeb854a1fba386"}, - {file = "kiwisolver-1.4.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d0005b053977e7b43388ddec89fa567f43d4f6d5c2c0affe57de5ebf290dc552"}, - {file = "kiwisolver-1.4.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2635d352d67458b66fd0667c14cb1d4145e9560d503219034a18a87e971ce4f3"}, - {file = "kiwisolver-1.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:767c23ad1c58c9e827b649a9ab7809fd5fd9db266a9cf02b0e926ddc2c680d58"}, - {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72d0eb9fba308b8311685c2268cf7d0a0639a6cd027d8128659f72bdd8a024b4"}, - {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f68e4f3eeca8fb22cc3d731f9715a13b652795ef657a13df1ad0c7dc0e9731df"}, - {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d84cd4061ae292d8ac367b2c3fa3aad11cb8625a95d135fe93f286f914f3f5a6"}, - {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a60ea74330b91bd22a29638940d115df9dc00af5035a9a2a6ad9399ffb4ceca5"}, - {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ce6a3a4e106cf35c2d9c4fa17c05ce0b180db622736845d4315519397a77beaf"}, - {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:77937e5e2a38a7b48eef0585114fe7930346993a88060d0bf886086d2aa49ef5"}, - {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:24c175051354f4a28c5d6a31c93906dc653e2bf234e8a4bbfb964892078898ce"}, - {file = "kiwisolver-1.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:0763515d4df10edf6d06a3c19734e2566368980d21ebec439f33f9eb936c07b7"}, - {file = "kiwisolver-1.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:0e4e2bf29574a6a7b7f6cb5fa69293b9f96c928949ac4a53ba3f525dffb87f9c"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d976bbb382b202f71c67f77b0ac11244021cfa3f7dfd9e562eefcea2df711548"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2489e4e5d7ef9a1c300a5e0196e43d9c739f066ef23270607d45aba368b91f2d"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e2ea9f7ab7fbf18fffb1b5434ce7c69a07582f7acc7717720f1d69f3e806f90c"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b34e51affded8faee0dfdb705416153819d8ea9250bbbf7ea1b249bdeb5f1122"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8aacd3d4b33b772542b2e01beb50187536967b514b00003bdda7589722d2a64"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7cf974dd4e35fa315563ac99d6287a1024e4dc2077b8a7d7cd3d2fb65d283134"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85bd218b5ecfbee8c8a82e121802dcb519a86044c9c3b2e4aef02fa05c6da370"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0856e241c2d3df4efef7c04a1e46b1936b6120c9bcf36dd216e3acd84bc4fb21"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9af39d6551f97d31a4deebeac6f45b156f9755ddc59c07b402c148f5dbb6482a"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:bb4ae2b57fc1d8cbd1cf7b1d9913803681ffa903e7488012be5b76dedf49297f"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aedff62918805fb62d43a4aa2ecd4482c380dc76cd31bd7c8878588a61bd0369"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:1fa333e8b2ce4d9660f2cda9c0e1b6bafcfb2457a9d259faa82289e73ec24891"}, - {file = "kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32"}, - {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4d1d9e582ad4d63062d34077a9a1e9f3c34088a2ec5135b1f7190c07cf366527"}, - {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:deed0c7258ceb4c44ad5ec7d9918f9f14fd05b2be86378d86cf50e63d1e7b771"}, - {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0a590506f303f512dff6b7f75fd2fd18e16943efee932008fe7140e5fa91d80e"}, - {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e09c2279a4d01f099f52d5c4b3d9e208e91edcbd1a175c9662a8b16e000fece9"}, - {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c9e7cdf45d594ee04d5be1b24dd9d49f3d1590959b2271fb30b5ca2b262c00fb"}, - {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:720e05574713db64c356e86732c0f3c5252818d05f9df320f0ad8380641acea5"}, - {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:17680d737d5335b552994a2008fab4c851bcd7de33094a82067ef3a576ff02fa"}, - {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85b5352f94e490c028926ea567fc569c52ec79ce131dadb968d3853e809518c2"}, - {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:464415881e4801295659462c49461a24fb107c140de781d55518c4b80cb6790f"}, - {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1"}, - {file = "kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d"}, -] - -[[package]] -name = "lazy-loader" -version = "0.4" -description = "Makes it easy to load subpackages and functions on demand." -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "lazy_loader-0.4-py3-none-any.whl", hash = "sha256:342aa8e14d543a154047afb4ba8ef17f5563baad3fc610d7b15b213b0f119efc"}, - {file = "lazy_loader-0.4.tar.gz", hash = "sha256:47c75182589b91a4e1a85a136c074285a5ad4d9f39c63e0d7fb76391c4574cd1"}, -] - -[package.dependencies] -packaging = "*" - -[package.extras] -dev = ["changelist (==0.5)"] -lint = ["pre-commit (==3.7.0)"] -test = ["pytest (>=7.4)", "pytest-cov (>=4.1)"] - -[[package]] -name = "markupsafe" -version = "3.0.3" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559"}, - {file = "markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419"}, - {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695"}, - {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591"}, - {file = "markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c"}, - {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f"}, - {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6"}, - {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1"}, - {file = "markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa"}, - {file = "markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8"}, - {file = "markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1"}, - {file = "markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad"}, - {file = "markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a"}, - {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50"}, - {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf"}, - {file = "markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f"}, - {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a"}, - {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115"}, - {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a"}, - {file = "markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19"}, - {file = "markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01"}, - {file = "markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c"}, - {file = "markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e"}, - {file = "markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce"}, - {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d"}, - {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d"}, - {file = "markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a"}, - {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b"}, - {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f"}, - {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b"}, - {file = "markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d"}, - {file = "markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c"}, - {file = "markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f"}, - {file = "markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795"}, - {file = "markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219"}, - {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6"}, - {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676"}, - {file = "markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9"}, - {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1"}, - {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc"}, - {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12"}, - {file = "markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed"}, - {file = "markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5"}, - {file = "markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485"}, - {file = "markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73"}, - {file = "markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37"}, - {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19"}, - {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025"}, - {file = "markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6"}, - {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f"}, - {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb"}, - {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009"}, - {file = "markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354"}, - {file = "markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218"}, - {file = "markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287"}, - {file = "markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe"}, - {file = "markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026"}, - {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737"}, - {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97"}, - {file = "markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d"}, - {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda"}, - {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf"}, - {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe"}, - {file = "markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9"}, - {file = "markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581"}, - {file = "markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4"}, - {file = "markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab"}, - {file = "markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175"}, - {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634"}, - {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50"}, - {file = "markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e"}, - {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5"}, - {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523"}, - {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc"}, - {file = "markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d"}, - {file = "markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9"}, - {file = "markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa"}, - {file = "markupsafe-3.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26"}, - {file = "markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc"}, - {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c"}, - {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42"}, - {file = "markupsafe-3.0.3-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b"}, - {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758"}, - {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2"}, - {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d"}, - {file = "markupsafe-3.0.3-cp39-cp39-win32.whl", hash = "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7"}, - {file = "markupsafe-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e"}, - {file = "markupsafe-3.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8"}, - {file = "markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698"}, -] - -[[package]] -name = "matplotlib" -version = "3.10.7" -description = "Python plotting package" -optional = false -python-versions = ">=3.10" -groups = ["main"] -files = [ - {file = "matplotlib-3.10.7-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7ac81eee3b7c266dd92cee1cd658407b16c57eed08c7421fa354ed68234de380"}, - {file = "matplotlib-3.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:667ecd5d8d37813a845053d8f5bf110b534c3c9f30e69ebd25d4701385935a6d"}, - {file = "matplotlib-3.10.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc1c51b846aca49a5a8b44fbba6a92d583a35c64590ad9e1e950dc88940a4297"}, - {file = "matplotlib-3.10.7-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a11c2e9e72e7de09b7b72e62f3df23317c888299c875e2b778abf1eda8c0a42"}, - {file = "matplotlib-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f19410b486fdd139885ace124e57f938c1e6a3210ea13dd29cab58f5d4bc12c7"}, - {file = "matplotlib-3.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:b498e9e4022f93de2d5a37615200ca01297ceebbb56fe4c833f46862a490f9e3"}, - {file = "matplotlib-3.10.7-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:53b492410a6cd66c7a471de6c924f6ede976e963c0f3097a3b7abfadddc67d0a"}, - {file = "matplotlib-3.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d9749313deb729f08207718d29c86246beb2ea3fdba753595b55901dee5d2fd6"}, - {file = "matplotlib-3.10.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2222c7ba2cbde7fe63032769f6eb7e83ab3227f47d997a8453377709b7fe3a5a"}, - {file = "matplotlib-3.10.7-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e91f61a064c92c307c5a9dc8c05dc9f8a68f0a3be199d9a002a0622e13f874a1"}, - {file = "matplotlib-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6f1851eab59ca082c95df5a500106bad73672645625e04538b3ad0f69471ffcc"}, - {file = "matplotlib-3.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:6516ce375109c60ceec579e699524e9d504cd7578506f01150f7a6bc174a775e"}, - {file = "matplotlib-3.10.7-cp311-cp311-win_arm64.whl", hash = "sha256:b172db79759f5f9bc13ef1c3ef8b9ee7b37b0247f987fbbbdaa15e4f87fd46a9"}, - {file = "matplotlib-3.10.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a0edb7209e21840e8361e91ea84ea676658aa93edd5f8762793dec77a4a6748"}, - {file = "matplotlib-3.10.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c380371d3c23e0eadf8ebff114445b9f970aff2010198d498d4ab4c3b41eea4f"}, - {file = "matplotlib-3.10.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d5f256d49fea31f40f166a5e3131235a5d2f4b7f44520b1cf0baf1ce568ccff0"}, - {file = "matplotlib-3.10.7-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11ae579ac83cdf3fb72573bb89f70e0534de05266728740d478f0f818983c695"}, - {file = "matplotlib-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4c14b6acd16cddc3569a2d515cfdd81c7a68ac5639b76548cfc1a9e48b20eb65"}, - {file = "matplotlib-3.10.7-cp312-cp312-win_amd64.whl", hash = "sha256:0d8c32b7ea6fb80b1aeff5a2ceb3fb9778e2759e899d9beff75584714afcc5ee"}, - {file = "matplotlib-3.10.7-cp312-cp312-win_arm64.whl", hash = "sha256:5f3f6d315dcc176ba7ca6e74c7768fb7e4cf566c49cb143f6bc257b62e634ed8"}, - {file = "matplotlib-3.10.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1d9d3713a237970569156cfb4de7533b7c4eacdd61789726f444f96a0d28f57f"}, - {file = "matplotlib-3.10.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:37a1fea41153dd6ee061d21ab69c9cf2cf543160b1b85d89cd3d2e2a7902ca4c"}, - {file = "matplotlib-3.10.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b3c4ea4948d93c9c29dc01c0c23eef66f2101bf75158c291b88de6525c55c3d1"}, - {file = "matplotlib-3.10.7-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22df30ffaa89f6643206cf13877191c63a50e8f800b038bc39bee9d2d4957632"}, - {file = "matplotlib-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b69676845a0a66f9da30e87f48be36734d6748024b525ec4710be40194282c84"}, - {file = "matplotlib-3.10.7-cp313-cp313-win_amd64.whl", hash = "sha256:744991e0cc863dd669c8dc9136ca4e6e0082be2070b9d793cbd64bec872a6815"}, - {file = "matplotlib-3.10.7-cp313-cp313-win_arm64.whl", hash = "sha256:fba2974df0bf8ce3c995fa84b79cde38326e0f7b5409e7a3a481c1141340bcf7"}, - {file = "matplotlib-3.10.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:932c55d1fa7af4423422cb6a492a31cbcbdbe68fd1a9a3f545aa5e7a143b5355"}, - {file = "matplotlib-3.10.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e38c2d581d62ee729a6e144c47a71b3f42fb4187508dbbf4fe71d5612c3433b"}, - {file = "matplotlib-3.10.7-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:786656bb13c237bbcebcd402f65f44dd61ead60ee3deb045af429d889c8dbc67"}, - {file = "matplotlib-3.10.7-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09d7945a70ea43bf9248f4b6582734c2fe726723204a76eca233f24cffc7ef67"}, - {file = "matplotlib-3.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d0b181e9fa8daf1d9f2d4c547527b167cb8838fc587deabca7b5c01f97199e84"}, - {file = "matplotlib-3.10.7-cp313-cp313t-win_amd64.whl", hash = "sha256:31963603041634ce1a96053047b40961f7a29eb8f9a62e80cc2c0427aa1d22a2"}, - {file = "matplotlib-3.10.7-cp313-cp313t-win_arm64.whl", hash = "sha256:aebed7b50aa6ac698c90f60f854b47e48cd2252b30510e7a1feddaf5a3f72cbf"}, - {file = "matplotlib-3.10.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d883460c43e8c6b173fef244a2341f7f7c0e9725c7fe68306e8e44ed9c8fb100"}, - {file = "matplotlib-3.10.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:07124afcf7a6504eafcb8ce94091c5898bbdd351519a1beb5c45f7a38c67e77f"}, - {file = "matplotlib-3.10.7-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c17398b709a6cce3d9fdb1595c33e356d91c098cd9486cb2cc21ea2ea418e715"}, - {file = "matplotlib-3.10.7-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7146d64f561498764561e9cd0ed64fcf582e570fc519e6f521e2d0cfd43365e1"}, - {file = "matplotlib-3.10.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90ad854c0a435da3104c01e2c6f0028d7e719b690998a2333d7218db80950722"}, - {file = "matplotlib-3.10.7-cp314-cp314-win_amd64.whl", hash = "sha256:4645fc5d9d20ffa3a39361fcdbcec731382763b623b72627806bf251b6388866"}, - {file = "matplotlib-3.10.7-cp314-cp314-win_arm64.whl", hash = "sha256:9257be2f2a03415f9105c486d304a321168e61ad450f6153d77c69504ad764bb"}, - {file = "matplotlib-3.10.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1e4bbad66c177a8fdfa53972e5ef8be72a5f27e6a607cec0d8579abd0f3102b1"}, - {file = "matplotlib-3.10.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d8eb7194b084b12feb19142262165832fc6ee879b945491d1c3d4660748020c4"}, - {file = "matplotlib-3.10.7-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d41379b05528091f00e1728004f9a8d7191260f3862178b88e8fd770206318"}, - {file = "matplotlib-3.10.7-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a74f79fafb2e177f240579bc83f0b60f82cc47d2f1d260f422a0627207008ca"}, - {file = "matplotlib-3.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:702590829c30aada1e8cef0568ddbffa77ca747b4d6e36c6d173f66e301f89cc"}, - {file = "matplotlib-3.10.7-cp314-cp314t-win_amd64.whl", hash = "sha256:f79d5de970fc90cd5591f60053aecfce1fcd736e0303d9f0bf86be649fa68fb8"}, - {file = "matplotlib-3.10.7-cp314-cp314t-win_arm64.whl", hash = "sha256:cb783436e47fcf82064baca52ce748af71725d0352e1d31564cbe9c95df92b9c"}, - {file = "matplotlib-3.10.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5c09cf8f2793f81368f49f118b6f9f937456362bee282eac575cca7f84cda537"}, - {file = "matplotlib-3.10.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:de66744b2bb88d5cd27e80dfc2ec9f0517d0a46d204ff98fe9e5f2864eb67657"}, - {file = "matplotlib-3.10.7-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:53cc80662dd197ece414dd5b66e07370201515a3eaf52e7c518c68c16814773b"}, - {file = "matplotlib-3.10.7-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:15112bcbaef211bd663fa935ec33313b948e214454d949b723998a43357b17b0"}, - {file = "matplotlib-3.10.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d2a959c640cdeecdd2ec3136e8ea0441da59bcaf58d67e9c590740addba2cb68"}, - {file = "matplotlib-3.10.7-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3886e47f64611046bc1db523a09dd0a0a6bed6081e6f90e13806dd1d1d1b5e91"}, - {file = "matplotlib-3.10.7.tar.gz", hash = "sha256:a06ba7e2a2ef9131c79c49e63dad355d2d878413a0376c1727c8b9335ff731c7"}, -] - -[package.dependencies] -contourpy = ">=1.0.1" -cycler = ">=0.10" -fonttools = ">=4.22.0" -kiwisolver = ">=1.3.1" -numpy = ">=1.23" -packaging = ">=20.0" -pillow = ">=8" -pyparsing = ">=3" -python-dateutil = ">=2.7" - -[package.extras] -dev = ["meson-python (>=0.13.1,<0.17.0)", "pybind11 (>=2.13.2,!=2.13.3)", "setuptools (>=64)", "setuptools_scm (>=7)"] - -[[package]] -name = "ml-dtypes" -version = "0.5.3" -description = "ml_dtypes is a stand-alone implementation of several NumPy dtype extensions used in machine learning." -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "ml_dtypes-0.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0a1d68a7cb53e3f640b2b6a34d12c0542da3dd935e560fdf463c0c77f339fc20"}, - {file = "ml_dtypes-0.5.3-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cd5a6c711b5350f3cbc2ac28def81cd1c580075ccb7955e61e9d8f4bfd40d24"}, - {file = "ml_dtypes-0.5.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdcf26c2dbc926b8a35ec8cbfad7eff1a8bd8239e12478caca83a1fc2c400dc2"}, - {file = "ml_dtypes-0.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:aecbd7c5272c82e54d5b99d8435fd10915d1bc704b7df15e4d9ca8dc3902be61"}, - {file = "ml_dtypes-0.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4a177b882667c69422402df6ed5c3428ce07ac2c1f844d8a1314944651439458"}, - {file = "ml_dtypes-0.5.3-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9849ce7267444c0a717c80c6900997de4f36e2815ce34ac560a3edb2d9a64cd2"}, - {file = "ml_dtypes-0.5.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c3f5ae0309d9f888fd825c2e9d0241102fadaca81d888f26f845bc8c13c1e4ee"}, - {file = "ml_dtypes-0.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:58e39349d820b5702bb6f94ea0cb2dc8ec62ee81c0267d9622067d8333596a46"}, - {file = "ml_dtypes-0.5.3-cp311-cp311-win_arm64.whl", hash = "sha256:66c2756ae6cfd7f5224e355c893cfd617fa2f747b8bbd8996152cbdebad9a184"}, - {file = "ml_dtypes-0.5.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:156418abeeda48ea4797db6776db3c5bdab9ac7be197c1233771e0880c304057"}, - {file = "ml_dtypes-0.5.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1db60c154989af253f6c4a34e8a540c2c9dce4d770784d426945e09908fbb177"}, - {file = "ml_dtypes-0.5.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1b255acada256d1fa8c35ed07b5f6d18bc21d1556f842fbc2d5718aea2cd9e55"}, - {file = "ml_dtypes-0.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:da65e5fd3eea434ccb8984c3624bc234ddcc0d9f4c81864af611aaebcc08a50e"}, - {file = "ml_dtypes-0.5.3-cp312-cp312-win_arm64.whl", hash = "sha256:8bb9cd1ce63096567f5f42851f5843b5a0ea11511e50039a7649619abfb4ba6d"}, - {file = "ml_dtypes-0.5.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5103856a225465371fe119f2fef737402b705b810bd95ad5f348e6e1a6ae21af"}, - {file = "ml_dtypes-0.5.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cae435a68861660af81fa3c5af16b70ca11a17275c5b662d9c6f58294e0f113"}, - {file = "ml_dtypes-0.5.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6936283b56d74fbec431ca57ce58a90a908fdbd14d4e2d22eea6d72bb208a7b7"}, - {file = "ml_dtypes-0.5.3-cp313-cp313-win_amd64.whl", hash = "sha256:d0f730a17cf4f343b2c7ad50cee3bd19e969e793d2be6ed911f43086460096e4"}, - {file = "ml_dtypes-0.5.3-cp313-cp313-win_arm64.whl", hash = "sha256:2db74788fc01914a3c7f7da0763427280adfc9cd377e9604b6b64eb8097284bd"}, - {file = "ml_dtypes-0.5.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:93c36a08a6d158db44f2eb9ce3258e53f24a9a4a695325a689494f0fdbc71770"}, - {file = "ml_dtypes-0.5.3-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0e44a3761f64bc009d71ddb6d6c71008ba21b53ab6ee588dadab65e2fa79eafc"}, - {file = "ml_dtypes-0.5.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdf40d2aaabd3913dec11840f0d0ebb1b93134f99af6a0a4fd88ffe924928ab4"}, - {file = "ml_dtypes-0.5.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:aec640bd94c4c85c0d11e2733bd13cbb10438fb004852996ec0efbc6cacdaf70"}, - {file = "ml_dtypes-0.5.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bda32ce212baa724e03c68771e5c69f39e584ea426bfe1a701cb01508ffc7035"}, - {file = "ml_dtypes-0.5.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c205cac07d24a29840c163d6469f61069ce4b065518519216297fc2f261f8db9"}, - {file = "ml_dtypes-0.5.3-cp314-cp314-win_amd64.whl", hash = "sha256:cd7c0bb22d4ff86d65ad61b5dd246812e8993fbc95b558553624c33e8b6903ea"}, - {file = "ml_dtypes-0.5.3-cp314-cp314-win_arm64.whl", hash = "sha256:9d55ea7f7baf2aed61bf1872116cefc9d0c3693b45cae3916897ee27ef4b835e"}, - {file = "ml_dtypes-0.5.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:e12e29764a0e66a7a31e9b8bf1de5cc0423ea72979f45909acd4292de834ccd3"}, - {file = "ml_dtypes-0.5.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19f6c3a4f635c2fc9e2aa7d91416bd7a3d649b48350c51f7f715a09370a90d93"}, - {file = "ml_dtypes-0.5.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ab039ffb40f3dc0aeeeba84fd6c3452781b5e15bef72e2d10bcb33e4bbffc39"}, - {file = "ml_dtypes-0.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5ee72568d46b9533ad54f78b1e1f3067c0534c5065120ea8ecc6f210d22748b3"}, - {file = "ml_dtypes-0.5.3-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:01de48de4537dc3c46e684b969a40ec36594e7eeb7c69e9a093e7239f030a28a"}, - {file = "ml_dtypes-0.5.3-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8b1a6e231b0770f2894910f1dce6d2f31d65884dbf7668f9b08d73623cdca909"}, - {file = "ml_dtypes-0.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:a4f39b9bf6555fab9bfb536cf5fdd1c1c727e8d22312078702e9ff005354b37f"}, - {file = "ml_dtypes-0.5.3.tar.gz", hash = "sha256:95ce33057ba4d05df50b1f3cfefab22e351868a843b3b15a46c65836283670c9"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, - {version = ">=1.23.3", markers = "python_version >= \"3.11\""}, - {version = ">=1.21.2", markers = "python_version >= \"3.10\""}, -] - -[package.extras] -dev = ["absl-py", "pyink", "pylint (>=2.6.0)", "pytest", "pytest-xdist"] - -[[package]] -name = "mpmath" -version = "1.3.0" -description = "Python library for arbitrary-precision floating-point arithmetic" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c"}, - {file = "mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f"}, -] - -[package.extras] -develop = ["codecov", "pycodestyle", "pytest (>=4.6)", "pytest-cov", "wheel"] -docs = ["sphinx"] -gmpy = ["gmpy2 (>=2.1.0a4) ; platform_python_implementation != \"PyPy\""] -tests = ["pytest (>=4.6)"] - -[[package]] -name = "networkx" -version = "3.4.2" -description = "Python package for creating and manipulating graphs and networks" -optional = false -python-versions = ">=3.10" -groups = ["main"] -markers = "python_version == \"3.10\"" -files = [ - {file = "networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f"}, - {file = "networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1"}, -] - -[package.extras] -default = ["matplotlib (>=3.7)", "numpy (>=1.24)", "pandas (>=2.0)", "scipy (>=1.10,!=1.11.0,!=1.11.1)"] -developer = ["changelist (==0.5)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] -doc = ["intersphinx-registry", "myst-nb (>=1.1)", "numpydoc (>=1.8.0)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.15)", "sphinx (>=7.3)", "sphinx-gallery (>=0.16)", "texext (>=0.6.7)"] -example = ["cairocffi (>=1.7)", "contextily (>=1.6)", "igraph (>=0.11)", "momepy (>=0.7.2)", "osmnx (>=1.9)", "scikit-learn (>=1.5)", "seaborn (>=0.13)"] -extra = ["lxml (>=4.6)", "pydot (>=3.0.1)", "pygraphviz (>=1.14)", "sympy (>=1.10)"] -test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] - -[[package]] -name = "networkx" -version = "3.5" -description = "Python package for creating and manipulating graphs and networks" -optional = false -python-versions = ">=3.11" -groups = ["main"] -markers = "python_version >= \"3.11\"" -files = [ - {file = "networkx-3.5-py3-none-any.whl", hash = "sha256:0030d386a9a06dee3565298b4a734b68589749a544acbb6c412dc9e2489ec6ec"}, - {file = "networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037"}, -] - -[package.extras] -default = ["matplotlib (>=3.8)", "numpy (>=1.25)", "pandas (>=2.0)", "scipy (>=1.11.2)"] -developer = ["mypy (>=1.15)", "pre-commit (>=4.1)"] -doc = ["intersphinx-registry", "myst-nb (>=1.1)", "numpydoc (>=1.8.0)", "pillow (>=10)", "pydata-sphinx-theme (>=0.16)", "sphinx (>=8.0)", "sphinx-gallery (>=0.18)", "texext (>=0.6.7)"] -example = ["cairocffi (>=1.7)", "contextily (>=1.6)", "igraph (>=0.11)", "momepy (>=0.7.2)", "osmnx (>=2.0.0)", "scikit-learn (>=1.5)", "seaborn (>=0.13)"] -extra = ["lxml (>=4.6)", "pydot (>=3.0.1)", "pygraphviz (>=1.14)", "sympy (>=1.10)"] -test = ["pytest (>=7.2)", "pytest-cov (>=4.0)", "pytest-xdist (>=3.0)"] -test-extras = ["pytest-mpl", "pytest-randomly"] - -[[package]] -name = "numpy" -version = "1.26.4" -description = "Fundamental package for array computing in Python" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, - {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, - {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, - {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, - {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, - {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, - {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, - {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, - {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, - {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, - {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, - {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, - {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, - {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, - {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, - {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, - {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, - {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, - {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, - {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, - {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, - {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, - {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, - {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, - {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, - {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, - {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, - {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, - {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, - {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, - {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, - {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, - {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, - {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, -] - -[[package]] -name = "nvidia-cublas-cu12" -version = "12.8.4.1" -description = "CUBLAS native runtime libraries" -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:b86f6dd8935884615a0683b663891d43781b819ac4f2ba2b0c9604676af346d0"}, - {file = "nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:8ac4e771d5a348c551b2a426eda6193c19aa630236b418086020df5ba9667142"}, - {file = "nvidia_cublas_cu12-12.8.4.1-py3-none-win_amd64.whl", hash = "sha256:47e9b82132fa8d2b4944e708049229601448aaad7e6f296f630f2d1a32de35af"}, -] - -[[package]] -name = "nvidia-cuda-cupti-cu12" -version = "12.8.90" -description = "CUDA profiling tools runtime libs." -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4412396548808ddfed3f17a467b104ba7751e6b58678a4b840675c56d21cf7ed"}, - {file = "nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea0cb07ebda26bb9b29ba82cda34849e73c166c18162d3913575b0c9db9a6182"}, - {file = "nvidia_cuda_cupti_cu12-12.8.90-py3-none-win_amd64.whl", hash = "sha256:bb479dcdf7e6d4f8b0b01b115260399bf34154a1a2e9fe11c85c517d87efd98e"}, -] - -[[package]] -name = "nvidia-cuda-nvrtc-cu12" -version = "12.8.93" -description = "NVRTC native runtime libraries" -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:a7756528852ef889772a84c6cd89d41dfa74667e24cca16bb31f8f061e3e9994"}, - {file = "nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fc1fec1e1637854b4c0a65fb9a8346b51dd9ee69e61ebaccc82058441f15bce8"}, - {file = "nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-win_amd64.whl", hash = "sha256:7a4b6b2904850fe78e0bd179c4b655c404d4bb799ef03ddc60804247099ae909"}, -] - -[[package]] -name = "nvidia-cuda-runtime-cu12" -version = "12.8.90" -description = "CUDA Runtime native Libraries" -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:52bf7bbee900262ffefe5e9d5a2a69a30d97e2bc5bb6cc866688caa976966e3d"}, - {file = "nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adade8dcbd0edf427b7204d480d6066d33902cab2a4707dcfc48a2d0fd44ab90"}, - {file = "nvidia_cuda_runtime_cu12-12.8.90-py3-none-win_amd64.whl", hash = "sha256:c0c6027f01505bfed6c3b21ec546f69c687689aad5f1a377554bc6ca4aa993a8"}, -] - -[[package]] -name = "nvidia-cudnn-cu12" -version = "9.10.2.21" -description = "cuDNN runtime libraries" -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:c9132cc3f8958447b4910a1720036d9eff5928cc3179b0a51fb6d167c6cc87d8"}, - {file = "nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8"}, - {file = "nvidia_cudnn_cu12-9.10.2.21-py3-none-win_amd64.whl", hash = "sha256:c6288de7d63e6cf62988f0923f96dc339cea362decb1bf5b3141883392a7d65e"}, -] - -[package.dependencies] -nvidia-cublas-cu12 = "*" - -[[package]] -name = "nvidia-cufft-cu12" -version = "11.3.3.83" -description = "CUFFT native runtime libraries" -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:848ef7224d6305cdb2a4df928759dca7b1201874787083b6e7550dd6765ce69a"}, - {file = "nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74"}, - {file = "nvidia_cufft_cu12-11.3.3.83-py3-none-win_amd64.whl", hash = "sha256:7a64a98ef2a7c47f905aaf8931b69a3a43f27c55530c698bb2ed7c75c0b42cb7"}, -] - -[package.dependencies] -nvidia-nvjitlink-cu12 = "*" - -[[package]] -name = "nvidia-cufile-cu12" -version = "1.13.1.3" -description = "cuFile GPUDirect libraries" -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d069003be650e131b21c932ec3d8969c1715379251f8d23a1860554b1cb24fc"}, - {file = "nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:4beb6d4cce47c1a0f1013d72e02b0994730359e17801d395bdcbf20cfb3bb00a"}, -] - -[[package]] -name = "nvidia-curand-cu12" -version = "10.3.9.90" -description = "CURAND native runtime libraries" -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:dfab99248034673b779bc6decafdc3404a8a6f502462201f2f31f11354204acd"}, - {file = "nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:b32331d4f4df5d6eefa0554c565b626c7216f87a06a4f56fab27c3b68a830ec9"}, - {file = "nvidia_curand_cu12-10.3.9.90-py3-none-win_amd64.whl", hash = "sha256:f149a8ca457277da854f89cf282d6ef43176861926c7ac85b2a0fbd237c587ec"}, -] - -[[package]] -name = "nvidia-cusolver-cu12" -version = "11.7.3.90" -description = "CUDA solver native runtime libraries" -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:db9ed69dbef9715071232caa9b69c52ac7de3a95773c2db65bdba85916e4e5c0"}, - {file = "nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450"}, - {file = "nvidia_cusolver_cu12-11.7.3.90-py3-none-win_amd64.whl", hash = "sha256:4a550db115fcabc4d495eb7d39ac8b58d4ab5d8e63274d3754df1c0ad6a22d34"}, -] - -[package.dependencies] -nvidia-cublas-cu12 = "*" -nvidia-cusparse-cu12 = "*" -nvidia-nvjitlink-cu12 = "*" - -[[package]] -name = "nvidia-cusparse-cu12" -version = "12.5.8.93" -description = "CUSPARSE native runtime libraries" -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9b6c161cb130be1a07a27ea6923df8141f3c295852f4b260c65f18f3e0a091dc"}, - {file = "nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b"}, - {file = "nvidia_cusparse_cu12-12.5.8.93-py3-none-win_amd64.whl", hash = "sha256:9a33604331cb2cac199f2e7f5104dfbb8a5a898c367a53dfda9ff2acb6b6b4dd"}, -] - -[package.dependencies] -nvidia-nvjitlink-cu12 = "*" - -[[package]] -name = "nvidia-cusparselt-cu12" -version = "0.7.1" -description = "NVIDIA cuSPARSELt" -optional = false -python-versions = "*" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8878dce784d0fac90131b6817b607e803c36e629ba34dc5b433471382196b6a5"}, - {file = "nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f1bb701d6b930d5a7cea44c19ceb973311500847f81b634d802b7b539dc55623"}, - {file = "nvidia_cusparselt_cu12-0.7.1-py3-none-win_amd64.whl", hash = "sha256:f67fbb5831940ec829c9117b7f33807db9f9678dc2a617fbe781cac17b4e1075"}, -] - -[[package]] -name = "nvidia-nccl-cu12" -version = "2.27.3" -description = "NVIDIA Collective Communication Library (NCCL) Runtime" -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_nccl_cu12-2.27.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9ddf1a245abc36c550870f26d537a9b6087fb2e2e3d6e0ef03374c6fd19d984f"}, - {file = "nvidia_nccl_cu12-2.27.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adf27ccf4238253e0b826bce3ff5fa532d65fc42322c8bfdfaf28024c0fbe039"}, -] - -[[package]] -name = "nvidia-nvjitlink-cu12" -version = "12.8.93" -description = "Nvidia JIT LTO Library" -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:81ff63371a7ebd6e6451970684f916be2eab07321b73c9d244dc2b4da7f73b88"}, - {file = "nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:adccd7161ace7261e01bb91e44e88da350895c270d23f744f0820c818b7229e7"}, - {file = "nvidia_nvjitlink_cu12-12.8.93-py3-none-win_amd64.whl", hash = "sha256:bd93fbeeee850917903583587f4fc3a4eafa022e34572251368238ab5e6bd67f"}, -] - -[[package]] -name = "nvidia-nvtx-cu12" -version = "12.8.90" -description = "NVIDIA Tools Extension" -optional = false -python-versions = ">=3" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d7ad891da111ebafbf7e015d34879f7112832fc239ff0d7d776b6cb685274615"}, - {file = "nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f"}, - {file = "nvidia_nvtx_cu12-12.8.90-py3-none-win_amd64.whl", hash = "sha256:619c8304aedc69f02ea82dd244541a83c3d9d40993381b3b590f1adaed3db41e"}, -] - -[[package]] -name = "nvtx" -version = "0.2.13" -description = "Python NVTX - Python code annotation library" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "nvtx-0.2.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:462bdcc65a12b53bfa3e7df564ddfb72092a030a923dccd1cf88c4b771ecae3f"}, - {file = "nvtx-0.2.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7874534af889ab7c2c63554c73119d193d2beb7671b551b7f43de5b97ceb5971"}, - {file = "nvtx-0.2.13-cp310-cp310-win_amd64.whl", hash = "sha256:4f26d04b5ea5b96096941cb9a7115a73454e9e9d5c247bfcd34ec584559cf9dd"}, - {file = "nvtx-0.2.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ad794a0c046ef268b2fb3b6812a35bb3bce5cd19207d164689943f0031ac45f"}, - {file = "nvtx-0.2.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5640ca4b8be2c19a8fc4ca8403d3c2598165ea27541940b4897138a7b0a717fe"}, - {file = "nvtx-0.2.13-cp311-cp311-win_amd64.whl", hash = "sha256:be6d53143cb2bd44e04aecdb7f3b34b48ded96f3673ae41362239d9f54bcfe27"}, - {file = "nvtx-0.2.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3435cbbffa132f6aaba3abdb01e71a1b961a20858b4cb791883895a25b9305d6"}, - {file = "nvtx-0.2.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:453d838dd1424a04303281ee57a73e2b8dca0e03039bc609a945861b8fe7d7d9"}, - {file = "nvtx-0.2.13-cp312-cp312-win_amd64.whl", hash = "sha256:0722d743e0e41e1fb866ebe6446e0cd0d268ca8671313f8da4f8c969956b74d3"}, - {file = "nvtx-0.2.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1561d2111c698b1b1075899ff9c3fa7ba83603fc27c2e8ef567de6bbbe85ce1"}, - {file = "nvtx-0.2.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:edd7b729ed0211350258a21dd13422f59bc521de2b2fd21feb6c177af492f4e1"}, - {file = "nvtx-0.2.13-cp313-cp313-win_amd64.whl", hash = "sha256:f0524bb71443d5a1f19a6409a9a81405fc437e53c5edfc4c44b6f4504ccf46e3"}, - {file = "nvtx-0.2.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88286e7f1bb098704b8fd58a08a1b0c0fd41843275bf23badb5e32f59e0b38b9"}, - {file = "nvtx-0.2.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ae27d5a2049f72b53bf6c061c3c8badeb8c33758b3eb31a888cca7afbbe3114"}, - {file = "nvtx-0.2.13-cp38-cp38-win_amd64.whl", hash = "sha256:e759bf6d97ff7a134cf290b251c4d55154a707d80131a00c043942e22caab089"}, - {file = "nvtx-0.2.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18634cffbcebd535c8e7c2cbac86a3e3313bd23975d7c3e811e063fbc0b6cb88"}, - {file = "nvtx-0.2.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ffa37591353296c1a81130d8231c6550ba5faf2f8e2fc87b851f69446a836cf"}, - {file = "nvtx-0.2.13-cp39-cp39-win_amd64.whl", hash = "sha256:65ba8e3d81bf34cb363042787b8e2189cda6af38749374997a36262e2219105e"}, - {file = "nvtx-0.2.13.tar.gz", hash = "sha256:9db7ba135168e14e1f038866100bf8ed42d3e00b404e9bc7b6280ee3af828b92"}, -] - -[package.extras] -docs = ["nvidia_sphinx_theme", "sphinx"] -test = ["Cython (==3.0.11)", "pytest", "setuptools"] - -[[package]] -name = "oauthlib" -version = "3.3.1" -description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "oauthlib-3.3.1-py3-none-any.whl", hash = "sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1"}, - {file = "oauthlib-3.3.1.tar.gz", hash = "sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9"}, -] - -[package.extras] -rsa = ["cryptography (>=3.0.0)"] -signals = ["blinker (>=1.4.0)"] -signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] - -[[package]] -name = "onnx" -version = "1.18.0" -description = "Open Neural Network Exchange" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "onnx-1.18.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:4a3b50d94620e2c7c1404d1d59bc53e665883ae3fecbd856cc86da0639fd0fc3"}, - {file = "onnx-1.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e189652dad6e70a0465035c55cc565c27aa38803dd4f4e74e4b952ee1c2de94b"}, - {file = "onnx-1.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfb1f271b1523b29f324bfd223f6a4cfbdc5a2f2f16e73563671932d33663365"}, - {file = "onnx-1.18.0-cp310-cp310-win32.whl", hash = "sha256:e03071041efd82e0317b3c45433b2f28146385b80f26f82039bc68048ac1a7a0"}, - {file = "onnx-1.18.0-cp310-cp310-win_amd64.whl", hash = "sha256:9235b3493951e11e75465d56f4cd97e3e9247f096160dd3466bfabe4cbc938bc"}, - {file = "onnx-1.18.0-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:735e06d8d0cf250dc498f54038831401063c655a8d6e5975b2527a4e7d24be3e"}, - {file = "onnx-1.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73160799472e1a86083f786fecdf864cf43d55325492a9b5a1cfa64d8a523ecc"}, - {file = "onnx-1.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6acafb3823238bbe8f4340c7ac32fb218689442e074d797bee1c5c9a02fdae75"}, - {file = "onnx-1.18.0-cp311-cp311-win32.whl", hash = "sha256:4c8c4bbda760c654e65eaffddb1a7de71ec02e60092d33f9000521f897c99be9"}, - {file = "onnx-1.18.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5810194f0f6be2e58c8d6dedc6119510df7a14280dd07ed5f0f0a85bd74816a"}, - {file = "onnx-1.18.0-cp311-cp311-win_arm64.whl", hash = "sha256:aa1b7483fac6cdec26922174fc4433f8f5c2f239b1133c5625063bb3b35957d0"}, - {file = "onnx-1.18.0-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:521bac578448667cbb37c50bf05b53c301243ede8233029555239930996a625b"}, - {file = "onnx-1.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4da451bf1c5ae381f32d430004a89f0405bc57a8471b0bddb6325a5b334aa40"}, - {file = "onnx-1.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99afac90b4cdb1471432203c3c1f74e16549c526df27056d39f41a9a47cfb4af"}, - {file = "onnx-1.18.0-cp312-cp312-win32.whl", hash = "sha256:ee159b41a3ae58d9c7341cf432fc74b96aaf50bd7bb1160029f657b40dc69715"}, - {file = "onnx-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:102c04edc76b16e9dfeda5a64c1fccd7d3d2913b1544750c01d38f1ac3c04e05"}, - {file = "onnx-1.18.0-cp312-cp312-win_arm64.whl", hash = "sha256:911b37d724a5d97396f3c2ef9ea25361c55cbc9aa18d75b12a52b620b67145af"}, - {file = "onnx-1.18.0-cp313-cp313-macosx_12_0_universal2.whl", hash = "sha256:030d9f5f878c5f4c0ff70a4545b90d7812cd6bfe511de2f3e469d3669c8cff95"}, - {file = "onnx-1.18.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8521544987d713941ee1e591520044d35e702f73dc87e91e6d4b15a064ae813d"}, - {file = "onnx-1.18.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c137eecf6bc618c2f9398bcc381474b55c817237992b169dfe728e169549e8f"}, - {file = "onnx-1.18.0-cp313-cp313-win32.whl", hash = "sha256:6c093ffc593e07f7e33862824eab9225f86aa189c048dd43ffde207d7041a55f"}, - {file = "onnx-1.18.0-cp313-cp313-win_amd64.whl", hash = "sha256:230b0fb615e5b798dc4a3718999ec1828360bc71274abd14f915135eab0255f1"}, - {file = "onnx-1.18.0-cp313-cp313-win_arm64.whl", hash = "sha256:6f91930c1a284135db0f891695a263fc876466bf2afbd2215834ac08f600cfca"}, - {file = "onnx-1.18.0-cp313-cp313t-macosx_12_0_universal2.whl", hash = "sha256:2f4d37b0b5c96a873887652d1cbf3f3c70821b8c66302d84b0f0d89dd6e47653"}, - {file = "onnx-1.18.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a69afd0baa372162948b52c13f3aa2730123381edf926d7ef3f68ca7cec6d0d0"}, - {file = "onnx-1.18.0-cp39-cp39-macosx_12_0_universal2.whl", hash = "sha256:a186b1518450e04dc3679da315a663a56429418e7ccfd947d721de9bd710b0ea"}, - {file = "onnx-1.18.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc22abacfb0d3cd024d6ab784cb5eb5aca9c966a791e8e13b1a4ecb93ddb47d3"}, - {file = "onnx-1.18.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7839bf2adb494e46ccf375a7936b5d9e241b63e1a84254f3eb2e2e184e3292c8"}, - {file = "onnx-1.18.0-cp39-cp39-win32.whl", hash = "sha256:2bd5c0c55669b6d8f12e859cc27f3a631fe58730871b21f001527e1d56219e2a"}, - {file = "onnx-1.18.0-cp39-cp39-win_amd64.whl", hash = "sha256:a3ff1735f99589be4f311eb586f2b949998614a82fb6261ae6af5a29879b9375"}, - {file = "onnx-1.18.0.tar.gz", hash = "sha256:3d8dbf9e996629131ba3aa1afd1d8239b660d1f830c6688dd7e03157cccd6b9c"}, -] - -[package.dependencies] -numpy = ">=1.22" -protobuf = ">=4.25.1" -typing_extensions = ">=4.7.1" - -[package.extras] -reference = ["Pillow", "google-re2 ; python_version < \"3.13\""] - -[[package]] -name = "onnx-graphsurgeon" -version = "0.5.2" -description = "ONNX GraphSurgeon" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "onnx_graphsurgeon-0.5.2-py2.py3-none-any.whl", hash = "sha256:10c130d6129fdeee02945f8103b5b112e6fd4d9b356e2dd3e80f53e0ebee7b5c"}, -] - -[package.dependencies] -numpy = "*" -onnx = ">=1.14.0" - -[[package]] -name = "onnx-ir" -version = "0.1.10" -description = "Efficient in-memory representation for ONNX" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "onnx_ir-0.1.10-py3-none-any.whl", hash = "sha256:55b6a1bd05e1448e2f8385875f1739f8d2e0dc7936ee25f0f5d2f6f7e2619144"}, - {file = "onnx_ir-0.1.10.tar.gz", hash = "sha256:513cda24f9710aa1160ec54bf7530ac0ffc3d4ca9e34ac2fb1e2448815bdf2a0"}, -] - -[package.dependencies] -ml_dtypes = ">=0.5.0" -numpy = "*" -onnx = ">=1.16" -typing_extensions = ">=4.10" - -[[package]] -name = "onnxscript" -version = "0.3.2" -description = "Naturally author ONNX functions and models using a subset of Python" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "onnxscript-0.3.2-py3-none-any.whl", hash = "sha256:220bbecccae228a285bd385159c47a09f003c623c9636afd56cc91df50706a88"}, - {file = "onnxscript-0.3.2.tar.gz", hash = "sha256:60820d4c3e39f8ea7d945dd4f96fa5dd23c3c2e111022512477c52c9e78eb3d4"}, -] - -[package.dependencies] -ml_dtypes = "*" -numpy = "*" -onnx = ">=1.16" -onnx_ir = ">=0.1.3,<2" -packaging = "*" -typing_extensions = ">=4.10" - -[[package]] -name = "opencv-python" -version = "4.11.0.86" -description = "Wrapper package for OpenCV python bindings." -optional = false -python-versions = ">=3.6" -groups = ["main"] -files = [ - {file = "opencv-python-4.11.0.86.tar.gz", hash = "sha256:03d60ccae62304860d232272e4a4fda93c39d595780cb40b161b310244b736a4"}, - {file = "opencv_python-4.11.0.86-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:432f67c223f1dc2824f5e73cdfcd9db0efc8710647d4e813012195dc9122a52a"}, - {file = "opencv_python-4.11.0.86-cp37-abi3-macosx_13_0_x86_64.whl", hash = "sha256:9d05ef13d23fe97f575153558653e2d6e87103995d54e6a35db3f282fe1f9c66"}, - {file = "opencv_python-4.11.0.86-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b92ae2c8852208817e6776ba1ea0d6b1e0a1b5431e971a2a0ddd2a8cc398202"}, - {file = "opencv_python-4.11.0.86-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b02611523803495003bd87362db3e1d2a0454a6a63025dc6658a9830570aa0d"}, - {file = "opencv_python-4.11.0.86-cp37-abi3-win32.whl", hash = "sha256:810549cb2a4aedaa84ad9a1c92fbfdfc14090e2749cedf2c1589ad8359aa169b"}, - {file = "opencv_python-4.11.0.86-cp37-abi3-win_amd64.whl", hash = "sha256:085ad9b77c18853ea66283e98affefe2de8cc4c1f43eda4c100cf9b2721142ec"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, - {version = ">=1.23.5", markers = "python_version == \"3.11\""}, - {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\""}, - {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\""}, -] - -[[package]] -name = "opencv-python-headless" -version = "4.8.0.74" -description = "Wrapper package for OpenCV python bindings." -optional = false -python-versions = ">=3.6" -groups = ["main"] -files = [ - {file = "opencv-python-headless-4.8.0.74.tar.gz", hash = "sha256:a72770b8f2e08358b1faa41c8372b17d040aa9bb3e446ab7090e358f6f4e91ba"}, - {file = "opencv_python_headless-4.8.0.74-cp37-abi3-macosx_10_16_x86_64.whl", hash = "sha256:f645b17667fc9bffec8c3b3a72a217430c8d7090ed3ebb80fd8efc657f372d6c"}, - {file = "opencv_python_headless-4.8.0.74-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:7c88744ce922b81747c86f2b7f1b3ec84ff2f53477ee9219a5e75ae2012b443f"}, - {file = "opencv_python_headless-4.8.0.74-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34e92fef90e8f768d92dca875aefaff8b11556427f82484378a3848eb690d4c0"}, - {file = "opencv_python_headless-4.8.0.74-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8a88620c43a5d17f7df8317767da93b935656ab9236df92e1e2e0dd23195756"}, - {file = "opencv_python_headless-4.8.0.74-cp37-abi3-win32.whl", hash = "sha256:b52a6eb2d92fff0f660e6aade958cb4373fbfcbafa0488f7ae88c4e6ce3f47f6"}, - {file = "opencv_python_headless-4.8.0.74-cp37-abi3-win_amd64.whl", hash = "sha256:19d30269ae710f67e0ae549361a68b755e28599a572d5f72d0bbb177ab438a28"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.23.5", markers = "python_version >= \"3.11\""}, - {version = ">=1.21.4", markers = "python_version == \"3.10\" and platform_system == \"Darwin\""}, - {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version == \"3.10\""}, -] - -[[package]] -name = "packaging" -version = "25.0" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, -] - -[[package]] -name = "pastedeploy" -version = "3.1.0" -description = "Load, configure, and compose WSGI applications and servers" -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "PasteDeploy-3.1.0-py3-none-any.whl", hash = "sha256:76388ad53a661448d436df28c798063108f70e994ddc749540d733cdbd1b38cf"}, - {file = "PasteDeploy-3.1.0.tar.gz", hash = "sha256:9ddbaf152f8095438a9fe81f82c78a6714b92ae8e066bed418b6a7ff6a095a95"}, -] - -[package.extras] -docs = ["Sphinx (>=1.7.5)", "pylons-sphinx-themes"] -paste = ["Paste"] -testing = ["Paste", "pytest", "pytest-cov"] - -[[package]] -name = "pbkdf2" -version = "1.3" -description = "PKCS#5 v2.0 PBKDF2 Module" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "pbkdf2-1.3.tar.gz", hash = "sha256:ac6397369f128212c43064a2b4878038dab78dab41875364554aaf2a684e6979"}, -] - -[[package]] -name = "peft" -version = "0.17.0" -description = "Parameter-Efficient Fine-Tuning (PEFT)" -optional = false -python-versions = ">=3.9.0" -groups = ["main"] -files = [ - {file = "peft-0.17.0-py3-none-any.whl", hash = "sha256:0190c28bdbdc24c3de549f2b42cd182cbb89d3e82aa3069c6db690c4ef6fccbb"}, - {file = "peft-0.17.0.tar.gz", hash = "sha256:cb647a931c8da434446d6a196c402b1c2d087b12e050e098215f906f12771f1e"}, -] - -[package.dependencies] -accelerate = ">=0.21.0" -huggingface_hub = ">=0.25.0" -numpy = ">=1.17" -packaging = ">=20.0" -psutil = "*" -pyyaml = "*" -safetensors = "*" -torch = ">=1.13.0" -tqdm = "*" -transformers = "*" - -[package.extras] -dev = ["black", "black", "hf-doc-builder", "hf-doc-builder", "ruff (>=0.9.2,<0.10.0)"] -docs-specific = ["black", "hf-doc-builder"] -quality = ["black", "hf-doc-builder", "ruff (>=0.9.2,<0.10.0)"] -test = ["black", "black", "datasets", "diffusers", "hf-doc-builder", "hf-doc-builder", "parameterized", "protobuf", "pytest", "pytest-cov", "pytest-xdist", "ruff (>=0.9.2,<0.10.0)", "scipy", "sentencepiece"] - -[[package]] -name = "pillow" -version = "11.3.0" -description = "Python Imaging Library (Fork)" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860"}, - {file = "pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad"}, - {file = "pillow-11.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0"}, - {file = "pillow-11.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b"}, - {file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50"}, - {file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae"}, - {file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9"}, - {file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e"}, - {file = "pillow-11.3.0-cp310-cp310-win32.whl", hash = "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6"}, - {file = "pillow-11.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f"}, - {file = "pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f"}, - {file = "pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722"}, - {file = "pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288"}, - {file = "pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d"}, - {file = "pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494"}, - {file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58"}, - {file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f"}, - {file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e"}, - {file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94"}, - {file = "pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0"}, - {file = "pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac"}, - {file = "pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd"}, - {file = "pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4"}, - {file = "pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69"}, - {file = "pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d"}, - {file = "pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6"}, - {file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7"}, - {file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024"}, - {file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809"}, - {file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d"}, - {file = "pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149"}, - {file = "pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d"}, - {file = "pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542"}, - {file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd"}, - {file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8"}, - {file = "pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f"}, - {file = "pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c"}, - {file = "pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd"}, - {file = "pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e"}, - {file = "pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1"}, - {file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805"}, - {file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8"}, - {file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2"}, - {file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b"}, - {file = "pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3"}, - {file = "pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51"}, - {file = "pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580"}, - {file = "pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e"}, - {file = "pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d"}, - {file = "pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced"}, - {file = "pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c"}, - {file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8"}, - {file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59"}, - {file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe"}, - {file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c"}, - {file = "pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788"}, - {file = "pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31"}, - {file = "pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e"}, - {file = "pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12"}, - {file = "pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a"}, - {file = "pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632"}, - {file = "pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673"}, - {file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027"}, - {file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77"}, - {file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874"}, - {file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a"}, - {file = "pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214"}, - {file = "pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635"}, - {file = "pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6"}, - {file = "pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae"}, - {file = "pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653"}, - {file = "pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6"}, - {file = "pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36"}, - {file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b"}, - {file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477"}, - {file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50"}, - {file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b"}, - {file = "pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12"}, - {file = "pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db"}, - {file = "pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa"}, - {file = "pillow-11.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f"}, - {file = "pillow-11.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081"}, - {file = "pillow-11.3.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4"}, - {file = "pillow-11.3.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc"}, - {file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06"}, - {file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a"}, - {file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978"}, - {file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d"}, - {file = "pillow-11.3.0-cp39-cp39-win32.whl", hash = "sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71"}, - {file = "pillow-11.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada"}, - {file = "pillow-11.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb"}, - {file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967"}, - {file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe"}, - {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c"}, - {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25"}, - {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27"}, - {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a"}, - {file = "pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f"}, - {file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6"}, - {file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438"}, - {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3"}, - {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c"}, - {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361"}, - {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7"}, - {file = "pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8"}, - {file = "pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] -fpx = ["olefile"] -mic = ["olefile"] -test-arrow = ["pyarrow"] -tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"] -typing = ["typing-extensions ; python_version < \"3.10\""] -xmp = ["defusedxml"] - -[[package]] -name = "plaster" -version = "1.1.2" -description = "A loader interface around multiple config file formats." -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "plaster-1.1.2-py2.py3-none-any.whl", hash = "sha256:42992ab1f4865f1278e2ad740e8ad145683bb4022e03534265528f0c23c0df2d"}, - {file = "plaster-1.1.2.tar.gz", hash = "sha256:f8befc54bf8c1147c10ab40297ec84c2676fa2d4ea5d6f524d9436a80074ef98"}, -] - -[package.extras] -docs = ["Sphinx", "pylons-sphinx-themes"] -testing = ["pytest", "pytest-cov"] - -[[package]] -name = "plaster-pastedeploy" -version = "1.0.1" -description = "A loader implementing the PasteDeploy syntax to be used by plaster." -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "plaster_pastedeploy-1.0.1-py2.py3-none-any.whl", hash = "sha256:ad3550cc744648969ed3b810f33c9344f515ee8d8a8cec18e8f2c4a643c2181f"}, - {file = "plaster_pastedeploy-1.0.1.tar.gz", hash = "sha256:be262e6d2e41a7264875daa2fe2850cbb0615728bcdc92828fdc72736e381412"}, -] - -[package.dependencies] -PasteDeploy = ">=2.0" -plaster = ">=0.5" - -[package.extras] -testing = ["pytest", "pytest-cov"] - -[[package]] -name = "polygraphy" -version = "0.49.22" -description = "Polygraphy: A Deep Learning Inference Prototyping and Debugging Toolkit" -optional = false -python-versions = ">=3.6" -groups = ["main"] -files = [ - {file = "polygraphy-0.49.22-py2.py3-none-any.whl", hash = "sha256:084fc57389f070f11e785a78dabbf2f4af2e2a16499d441b4483e880b426b42f"}, -] - -[[package]] -name = "protobuf" -version = "6.32.1" -description = "" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "protobuf-6.32.1-cp310-abi3-win32.whl", hash = "sha256:a8a32a84bc9f2aad712041b8b366190f71dde248926da517bde9e832e4412085"}, - {file = "protobuf-6.32.1-cp310-abi3-win_amd64.whl", hash = "sha256:b00a7d8c25fa471f16bc8153d0e53d6c9e827f0953f3c09aaa4331c718cae5e1"}, - {file = "protobuf-6.32.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d8c7e6eb619ffdf105ee4ab76af5a68b60a9d0f66da3ea12d1640e6d8dab7281"}, - {file = "protobuf-6.32.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:2f5b80a49e1eb7b86d85fcd23fe92df154b9730a725c3b38c4e43b9d77018bf4"}, - {file = "protobuf-6.32.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:b1864818300c297265c83a4982fd3169f97122c299f56a56e2445c3698d34710"}, - {file = "protobuf-6.32.1-cp39-cp39-win32.whl", hash = "sha256:68ff170bac18c8178f130d1ccb94700cf72852298e016a2443bdb9502279e5f1"}, - {file = "protobuf-6.32.1-cp39-cp39-win_amd64.whl", hash = "sha256:d0975d0b2f3e6957111aa3935d08a0eb7e006b1505d825f862a1fffc8348e122"}, - {file = "protobuf-6.32.1-py3-none-any.whl", hash = "sha256:2601b779fc7d32a866c6b4404f9d42a3f67c5b9f3f15b4db3cccabe06b95c346"}, - {file = "protobuf-6.32.1.tar.gz", hash = "sha256:ee2469e4a021474ab9baafea6cd070e5bf27c7d29433504ddea1a4ee5850f68d"}, -] - -[[package]] -name = "psutil" -version = "7.1.0" -description = "Cross-platform lib for process and system monitoring." -optional = false -python-versions = ">=3.6" -groups = ["main"] -files = [ - {file = "psutil-7.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:76168cef4397494250e9f4e73eb3752b146de1dd950040b29186d0cce1d5ca13"}, - {file = "psutil-7.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:5d007560c8c372efdff9e4579c2846d71de737e4605f611437255e81efcca2c5"}, - {file = "psutil-7.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22e4454970b32472ce7deaa45d045b34d3648ce478e26a04c7e858a0a6e75ff3"}, - {file = "psutil-7.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c70e113920d51e89f212dd7be06219a9b88014e63a4cec69b684c327bc474e3"}, - {file = "psutil-7.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d4a113425c037300de3ac8b331637293da9be9713855c4fc9d2d97436d7259d"}, - {file = "psutil-7.1.0-cp37-abi3-win32.whl", hash = "sha256:09ad740870c8d219ed8daae0ad3b726d3bf9a028a198e7f3080f6a1888b99bca"}, - {file = "psutil-7.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:57f5e987c36d3146c0dd2528cd42151cf96cd359b9d67cfff836995cc5df9a3d"}, - {file = "psutil-7.1.0-cp37-abi3-win_arm64.whl", hash = "sha256:6937cb68133e7c97b6cc9649a570c9a18ba0efebed46d8c5dae4c07fa1b67a07"}, - {file = "psutil-7.1.0.tar.gz", hash = "sha256:655708b3c069387c8b77b072fc429a57d0e214221d01c0a772df7dfedcb3bcd2"}, -] - -[package.extras] -dev = ["abi3audit", "black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pyreadline ; os_name == \"nt\"", "pytest", "pytest-cov", "pytest-instafail", "pytest-subtests", "pytest-xdist", "pywin32 ; os_name == \"nt\" and platform_python_implementation != \"PyPy\"", "requests", "rstcheck", "ruff", "setuptools", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "vulture", "wheel", "wheel ; os_name == \"nt\" and platform_python_implementation != \"PyPy\"", "wmi ; os_name == \"nt\" and platform_python_implementation != \"PyPy\""] -test = ["pytest", "pytest-instafail", "pytest-subtests", "pytest-xdist", "pywin32 ; os_name == \"nt\" and platform_python_implementation != \"PyPy\"", "setuptools", "wheel ; os_name == \"nt\" and platform_python_implementation != \"PyPy\"", "wmi ; os_name == \"nt\" and platform_python_implementation != \"PyPy\""] - -[[package]] -name = "pyparsing" -version = "3.2.5" -description = "pyparsing - Classes and methods to define and execute parsing grammars" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e"}, - {file = "pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "pyramid" -version = "2.0.2" -description = "The Pyramid Web Framework, a Pylons project" -optional = false -python-versions = ">=3.6" -groups = ["main"] -files = [ - {file = "pyramid-2.0.2-py3-none-any.whl", hash = "sha256:2e6585ac55c147f0a51bc00dadf72075b3bdd9a871b332ff9e5e04117ccd76fa"}, - {file = "pyramid-2.0.2.tar.gz", hash = "sha256:372138a738e4216535cc76dcce6eddd5a1aaca95130f2354fb834264c06f18de"}, -] - -[package.dependencies] -hupper = ">=1.5" -plaster = "*" -plaster-pastedeploy = "*" -setuptools = "*" -translationstring = ">=0.4" -venusian = ">=1.0" -webob = ">=1.8.3" -"zope.deprecation" = ">=3.5.0" -"zope.interface" = ">=3.8.0" - -[package.extras] -docs = ["Sphinx (>=3.0.0)", "docutils", "pylons-sphinx-latesturl", "pylons-sphinx-themes (>=1.0.8)", "repoze.sphinx.autointerface", "sphinx-copybutton", "sphinxcontrib-autoprogram"] -testing = ["coverage", "pytest (>=5.4.2)", "pytest-cov", "webtest (>=1.3.1)", "zope.component (>=4.0)"] - -[[package]] -name = "pyramid-mailer" -version = "0.15.1" -description = "Sendmail package for Pyramid" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "pyramid_mailer-0.15.1-py2.py3-none-any.whl", hash = "sha256:28d4a7829ebc19dd40e712d8cb1998cec03c296ba675b2c112a503539738bdc1"}, - {file = "pyramid_mailer-0.15.1.tar.gz", hash = "sha256:ec0aff54d9179b2aa2922ff82c2016a4dc8d1da5dc3408d6594f0e2096446f9b"}, -] - -[package.dependencies] -pyramid = "*" -"repoze.sendmail" = ">=4.1" -transaction = "*" - -[package.extras] -docs = ["Sphinx", "docutils", "pylons-sphinx-themes (>=0.3)", "repoze.sphinx.autointerface"] -testing = ["WebTest", "coverage", "nose"] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main"] -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "python-openid" -version = "2.2.5" -description = "OpenID support for servers and consumers." -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "python-openid-2.2.5.tar.gz", hash = "sha256:92c51c3ecec846cbec4aeff11f9ff47303d4a63f93b0e6ac0ec02a091fed70ef"}, - {file = "python-openid-2.2.5.zip", hash = "sha256:c2d133e47e0a7705c9272eef00d7a09c174f5bf17a127fed8e2c6499556cc782"}, -] - -[[package]] -name = "pyyaml" -version = "6.0.3" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f"}, - {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4"}, - {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3"}, - {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6"}, - {file = "PyYAML-6.0.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369"}, - {file = "PyYAML-6.0.3-cp38-cp38-win32.whl", hash = "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295"}, - {file = "PyYAML-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b"}, - {file = "pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b"}, - {file = "pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956"}, - {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8"}, - {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198"}, - {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b"}, - {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0"}, - {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69"}, - {file = "pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e"}, - {file = "pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c"}, - {file = "pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e"}, - {file = "pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824"}, - {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c"}, - {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00"}, - {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"}, - {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a"}, - {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4"}, - {file = "pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b"}, - {file = "pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"}, - {file = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"}, - {file = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"}, - {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28"}, - {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c"}, - {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"}, - {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e"}, - {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea"}, - {file = "pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"}, - {file = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"}, - {file = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"}, - {file = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"}, - {file = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"}, - {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"}, - {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"}, - {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"}, - {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"}, - {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"}, - {file = "pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"}, - {file = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"}, - {file = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"}, - {file = "pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac"}, - {file = "pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310"}, - {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7"}, - {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788"}, - {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5"}, - {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764"}, - {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35"}, - {file = "pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac"}, - {file = "pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3"}, - {file = "pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3"}, - {file = "pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba"}, - {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c"}, - {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702"}, - {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c"}, - {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065"}, - {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65"}, - {file = "pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9"}, - {file = "pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b"}, - {file = "pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da"}, - {file = "pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917"}, - {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9"}, - {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5"}, - {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a"}, - {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926"}, - {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7"}, - {file = "pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0"}, - {file = "pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007"}, - {file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"}, -] - -[[package]] -name = "regex" -version = "2025.9.18" -description = "Alternative regular expression module, to replace re." -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "regex-2025.9.18-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:12296202480c201c98a84aecc4d210592b2f55e200a1d193235c4db92b9f6788"}, - {file = "regex-2025.9.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:220381f1464a581f2ea988f2220cf2a67927adcef107d47d6897ba5a2f6d51a4"}, - {file = "regex-2025.9.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:87f681bfca84ebd265278b5daa1dcb57f4db315da3b5d044add7c30c10442e61"}, - {file = "regex-2025.9.18-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34d674cbba70c9398074c8a1fcc1a79739d65d1105de2a3c695e2b05ea728251"}, - {file = "regex-2025.9.18-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:385c9b769655cb65ea40b6eea6ff763cbb6d69b3ffef0b0db8208e1833d4e746"}, - {file = "regex-2025.9.18-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8900b3208e022570ae34328712bef6696de0804c122933414014bae791437ab2"}, - {file = "regex-2025.9.18-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c204e93bf32cd7a77151d44b05eb36f469d0898e3fba141c026a26b79d9914a0"}, - {file = "regex-2025.9.18-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3acc471d1dd7e5ff82e6cacb3b286750decd949ecd4ae258696d04f019817ef8"}, - {file = "regex-2025.9.18-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6479d5555122433728760e5f29edb4c2b79655a8deb681a141beb5c8a025baea"}, - {file = "regex-2025.9.18-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:431bd2a8726b000eb6f12429c9b438a24062a535d06783a93d2bcbad3698f8a8"}, - {file = "regex-2025.9.18-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0cc3521060162d02bd36927e20690129200e5ac9d2c6d32b70368870b122db25"}, - {file = "regex-2025.9.18-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a021217b01be2d51632ce056d7a837d3fa37c543ede36e39d14063176a26ae29"}, - {file = "regex-2025.9.18-cp310-cp310-win32.whl", hash = "sha256:4a12a06c268a629cb67cc1d009b7bb0be43e289d00d5111f86a2efd3b1949444"}, - {file = "regex-2025.9.18-cp310-cp310-win_amd64.whl", hash = "sha256:47acd811589301298c49db2c56bde4f9308d6396da92daf99cba781fa74aa450"}, - {file = "regex-2025.9.18-cp310-cp310-win_arm64.whl", hash = "sha256:16bd2944e77522275e5ee36f867e19995bcaa533dcb516753a26726ac7285442"}, - {file = "regex-2025.9.18-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:51076980cd08cd13c88eb7365427ae27f0d94e7cebe9ceb2bb9ffdae8fc4d82a"}, - {file = "regex-2025.9.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:828446870bd7dee4e0cbeed767f07961aa07f0ea3129f38b3ccecebc9742e0b8"}, - {file = "regex-2025.9.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c28821d5637866479ec4cc23b8c990f5bc6dd24e5e4384ba4a11d38a526e1414"}, - {file = "regex-2025.9.18-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:726177ade8e481db669e76bf99de0b278783be8acd11cef71165327abd1f170a"}, - {file = "regex-2025.9.18-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f5cca697da89b9f8ea44115ce3130f6c54c22f541943ac8e9900461edc2b8bd4"}, - {file = "regex-2025.9.18-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:dfbde38f38004703c35666a1e1c088b778e35d55348da2b7b278914491698d6a"}, - {file = "regex-2025.9.18-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f2f422214a03fab16bfa495cfec72bee4aaa5731843b771860a471282f1bf74f"}, - {file = "regex-2025.9.18-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a295916890f4df0902e4286bc7223ee7f9e925daa6dcdec4192364255b70561a"}, - {file = "regex-2025.9.18-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:5db95ff632dbabc8c38c4e82bf545ab78d902e81160e6e455598014f0abe66b9"}, - {file = "regex-2025.9.18-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fb967eb441b0f15ae610b7069bdb760b929f267efbf522e814bbbfffdf125ce2"}, - {file = "regex-2025.9.18-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f04d2f20da4053d96c08f7fde6e1419b7ec9dbcee89c96e3d731fca77f411b95"}, - {file = "regex-2025.9.18-cp311-cp311-win32.whl", hash = "sha256:895197241fccf18c0cea7550c80e75f185b8bd55b6924fcae269a1a92c614a07"}, - {file = "regex-2025.9.18-cp311-cp311-win_amd64.whl", hash = "sha256:7e2b414deae99166e22c005e154a5513ac31493db178d8aec92b3269c9cce8c9"}, - {file = "regex-2025.9.18-cp311-cp311-win_arm64.whl", hash = "sha256:fb137ec7c5c54f34a25ff9b31f6b7b0c2757be80176435bf367111e3f71d72df"}, - {file = "regex-2025.9.18-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:436e1b31d7efd4dcd52091d076482031c611dde58bf9c46ca6d0a26e33053a7e"}, - {file = "regex-2025.9.18-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c190af81e5576b9c5fdc708f781a52ff20f8b96386c6e2e0557a78402b029f4a"}, - {file = "regex-2025.9.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e4121f1ce2b2b5eec4b397cc1b277686e577e658d8f5870b7eb2d726bd2300ab"}, - {file = "regex-2025.9.18-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:300e25dbbf8299d87205e821a201057f2ef9aa3deb29caa01cd2cac669e508d5"}, - {file = "regex-2025.9.18-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7b47fcf9f5316c0bdaf449e879407e1b9937a23c3b369135ca94ebc8d74b1742"}, - {file = "regex-2025.9.18-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:57a161bd3acaa4b513220b49949b07e252165e6b6dc910ee7617a37ff4f5b425"}, - {file = "regex-2025.9.18-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f130c3a7845ba42de42f380fff3c8aebe89a810747d91bcf56d40a069f15352"}, - {file = "regex-2025.9.18-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f96fa342b6f54dcba928dd452e8d8cb9f0d63e711d1721cd765bb9f73bb048d"}, - {file = "regex-2025.9.18-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0f0d676522d68c207828dcd01fb6f214f63f238c283d9f01d85fc664c7c85b56"}, - {file = "regex-2025.9.18-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:40532bff8a1a0621e7903ae57fce88feb2e8a9a9116d341701302c9302aef06e"}, - {file = "regex-2025.9.18-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:039f11b618ce8d71a1c364fdee37da1012f5a3e79b1b2819a9f389cd82fd6282"}, - {file = "regex-2025.9.18-cp312-cp312-win32.whl", hash = "sha256:e1dd06f981eb226edf87c55d523131ade7285137fbde837c34dc9d1bf309f459"}, - {file = "regex-2025.9.18-cp312-cp312-win_amd64.whl", hash = "sha256:3d86b5247bf25fa3715e385aa9ff272c307e0636ce0c9595f64568b41f0a9c77"}, - {file = "regex-2025.9.18-cp312-cp312-win_arm64.whl", hash = "sha256:032720248cbeeae6444c269b78cb15664458b7bb9ed02401d3da59fe4d68c3a5"}, - {file = "regex-2025.9.18-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2a40f929cd907c7e8ac7566ac76225a77701a6221bca937bdb70d56cb61f57b2"}, - {file = "regex-2025.9.18-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c90471671c2cdf914e58b6af62420ea9ecd06d1554d7474d50133ff26ae88feb"}, - {file = "regex-2025.9.18-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1a351aff9e07a2dabb5022ead6380cff17a4f10e4feb15f9100ee56c4d6d06af"}, - {file = "regex-2025.9.18-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bc4b8e9d16e20ddfe16430c23468a8707ccad3365b06d4536142e71823f3ca29"}, - {file = "regex-2025.9.18-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4b8cdbddf2db1c5e80338ba2daa3cfa3dec73a46fff2a7dda087c8efbf12d62f"}, - {file = "regex-2025.9.18-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a276937d9d75085b2c91fb48244349c6954f05ee97bba0963ce24a9d915b8b68"}, - {file = "regex-2025.9.18-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:92a8e375ccdc1256401c90e9dc02b8642894443d549ff5e25e36d7cf8a80c783"}, - {file = "regex-2025.9.18-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0dc6893b1f502d73037cf807a321cdc9be29ef3d6219f7970f842475873712ac"}, - {file = "regex-2025.9.18-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a61e85bfc63d232ac14b015af1261f826260c8deb19401c0597dbb87a864361e"}, - {file = "regex-2025.9.18-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1ef86a9ebc53f379d921fb9a7e42b92059ad3ee800fcd9e0fe6181090e9f6c23"}, - {file = "regex-2025.9.18-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d3bc882119764ba3a119fbf2bd4f1b47bc56c1da5d42df4ed54ae1e8e66fdf8f"}, - {file = "regex-2025.9.18-cp313-cp313-win32.whl", hash = "sha256:3810a65675845c3bdfa58c3c7d88624356dd6ee2fc186628295e0969005f928d"}, - {file = "regex-2025.9.18-cp313-cp313-win_amd64.whl", hash = "sha256:16eaf74b3c4180ede88f620f299e474913ab6924d5c4b89b3833bc2345d83b3d"}, - {file = "regex-2025.9.18-cp313-cp313-win_arm64.whl", hash = "sha256:4dc98ba7dd66bd1261927a9f49bd5ee2bcb3660f7962f1ec02617280fc00f5eb"}, - {file = "regex-2025.9.18-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:fe5d50572bc885a0a799410a717c42b1a6b50e2f45872e2b40f4f288f9bce8a2"}, - {file = "regex-2025.9.18-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1b9d9a2d6cda6621551ca8cf7a06f103adf72831153f3c0d982386110870c4d3"}, - {file = "regex-2025.9.18-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:13202e4c4ac0ef9a317fff817674b293c8f7e8c68d3190377d8d8b749f566e12"}, - {file = "regex-2025.9.18-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:874ff523b0fecffb090f80ae53dc93538f8db954c8bb5505f05b7787ab3402a0"}, - {file = "regex-2025.9.18-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d13ab0490128f2bb45d596f754148cd750411afc97e813e4b3a61cf278a23bb6"}, - {file = "regex-2025.9.18-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:05440bc172bc4b4b37fb9667e796597419404dbba62e171e1f826d7d2a9ebcef"}, - {file = "regex-2025.9.18-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5514b8e4031fdfaa3d27e92c75719cbe7f379e28cacd939807289bce76d0e35a"}, - {file = "regex-2025.9.18-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:65d3c38c39efce73e0d9dc019697b39903ba25b1ad45ebbd730d2cf32741f40d"}, - {file = "regex-2025.9.18-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ae77e447ebc144d5a26d50055c6ddba1d6ad4a865a560ec7200b8b06bc529368"}, - {file = "regex-2025.9.18-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e3ef8cf53dc8df49d7e28a356cf824e3623764e9833348b655cfed4524ab8a90"}, - {file = "regex-2025.9.18-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9feb29817df349c976da9a0debf775c5c33fc1c8ad7b9f025825da99374770b7"}, - {file = "regex-2025.9.18-cp313-cp313t-win32.whl", hash = "sha256:168be0d2f9b9d13076940b1ed774f98595b4e3c7fc54584bba81b3cc4181742e"}, - {file = "regex-2025.9.18-cp313-cp313t-win_amd64.whl", hash = "sha256:d59ecf3bb549e491c8104fea7313f3563c7b048e01287db0a90485734a70a730"}, - {file = "regex-2025.9.18-cp313-cp313t-win_arm64.whl", hash = "sha256:dbef80defe9fb21310948a2595420b36c6d641d9bea4c991175829b2cc4bc06a"}, - {file = "regex-2025.9.18-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c6db75b51acf277997f3adcd0ad89045d856190d13359f15ab5dda21581d9129"}, - {file = "regex-2025.9.18-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8f9698b6f6895d6db810e0bda5364f9ceb9e5b11328700a90cae573574f61eea"}, - {file = "regex-2025.9.18-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:29cd86aa7cb13a37d0f0d7c21d8d949fe402ffa0ea697e635afedd97ab4b69f1"}, - {file = "regex-2025.9.18-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c9f285a071ee55cd9583ba24dde006e53e17780bb309baa8e4289cd472bcc47"}, - {file = "regex-2025.9.18-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5adf266f730431e3be9021d3e5b8d5ee65e563fec2883ea8093944d21863b379"}, - {file = "regex-2025.9.18-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1137cabc0f38807de79e28d3f6e3e3f2cc8cfb26bead754d02e6d1de5f679203"}, - {file = "regex-2025.9.18-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7cc9e5525cada99699ca9223cce2d52e88c52a3d2a0e842bd53de5497c604164"}, - {file = "regex-2025.9.18-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bbb9246568f72dce29bcd433517c2be22c7791784b223a810225af3b50d1aafb"}, - {file = "regex-2025.9.18-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:6a52219a93dd3d92c675383efff6ae18c982e2d7651c792b1e6d121055808743"}, - {file = "regex-2025.9.18-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:ae9b3840c5bd456780e3ddf2f737ab55a79b790f6409182012718a35c6d43282"}, - {file = "regex-2025.9.18-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d488c236ac497c46a5ac2005a952c1a0e22a07be9f10c3e735bc7d1209a34773"}, - {file = "regex-2025.9.18-cp314-cp314-win32.whl", hash = "sha256:0c3506682ea19beefe627a38872d8da65cc01ffa25ed3f2e422dffa1474f0788"}, - {file = "regex-2025.9.18-cp314-cp314-win_amd64.whl", hash = "sha256:57929d0f92bebb2d1a83af372cd0ffba2263f13f376e19b1e4fa32aec4efddc3"}, - {file = "regex-2025.9.18-cp314-cp314-win_arm64.whl", hash = "sha256:6a4b44df31d34fa51aa5c995d3aa3c999cec4d69b9bd414a8be51984d859f06d"}, - {file = "regex-2025.9.18-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:b176326bcd544b5e9b17d6943f807697c0cb7351f6cfb45bf5637c95ff7e6306"}, - {file = "regex-2025.9.18-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:0ffd9e230b826b15b369391bec167baed57c7ce39efc35835448618860995946"}, - {file = "regex-2025.9.18-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec46332c41add73f2b57e2f5b642f991f6b15e50e9f86285e08ffe3a512ac39f"}, - {file = "regex-2025.9.18-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b80fa342ed1ea095168a3f116637bd1030d39c9ff38dc04e54ef7c521e01fc95"}, - {file = "regex-2025.9.18-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f4d97071c0ba40f0cf2a93ed76e660654c399a0a04ab7d85472239460f3da84b"}, - {file = "regex-2025.9.18-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0ac936537ad87cef9e0e66c5144484206c1354224ee811ab1519a32373e411f3"}, - {file = "regex-2025.9.18-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dec57f96d4def58c422d212d414efe28218d58537b5445cf0c33afb1b4768571"}, - {file = "regex-2025.9.18-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:48317233294648bf7cd068857f248e3a57222259a5304d32c7552e2284a1b2ad"}, - {file = "regex-2025.9.18-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:274687e62ea3cf54846a9b25fc48a04459de50af30a7bd0b61a9e38015983494"}, - {file = "regex-2025.9.18-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a78722c86a3e7e6aadf9579e3b0ad78d955f2d1f1a8ca4f67d7ca258e8719d4b"}, - {file = "regex-2025.9.18-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:06104cd203cdef3ade989a1c45b6215bf42f8b9dd705ecc220c173233f7cba41"}, - {file = "regex-2025.9.18-cp314-cp314t-win32.whl", hash = "sha256:2e1eddc06eeaffd249c0adb6fafc19e2118e6308c60df9db27919e96b5656096"}, - {file = "regex-2025.9.18-cp314-cp314t-win_amd64.whl", hash = "sha256:8620d247fb8c0683ade51217b459cb4a1081c0405a3072235ba43a40d355c09a"}, - {file = "regex-2025.9.18-cp314-cp314t-win_arm64.whl", hash = "sha256:b7531a8ef61de2c647cdf68b3229b071e46ec326b3138b2180acb4275f470b01"}, - {file = "regex-2025.9.18-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3dbcfcaa18e9480669030d07371713c10b4f1a41f791ffa5cb1a99f24e777f40"}, - {file = "regex-2025.9.18-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1e85f73ef7095f0380208269055ae20524bfde3f27c5384126ddccf20382a638"}, - {file = "regex-2025.9.18-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9098e29b3ea4ffffeade423f6779665e2a4f8db64e699c0ed737ef0db6ba7b12"}, - {file = "regex-2025.9.18-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90b6b7a2d0f45b7ecaaee1aec6b362184d6596ba2092dd583ffba1b78dd0231c"}, - {file = "regex-2025.9.18-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c81b892af4a38286101502eae7aec69f7cd749a893d9987a92776954f3943408"}, - {file = "regex-2025.9.18-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3b524d010973f2e1929aeb635418d468d869a5f77b52084d9f74c272189c251d"}, - {file = "regex-2025.9.18-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b498437c026a3d5d0be0020023ff76d70ae4d77118e92f6f26c9d0423452446"}, - {file = "regex-2025.9.18-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0716e4d6e58853d83f6563f3cf25c281ff46cf7107e5f11879e32cb0b59797d9"}, - {file = "regex-2025.9.18-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:065b6956749379d41db2625f880b637d4acc14c0a4de0d25d609a62850e96d36"}, - {file = "regex-2025.9.18-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d4a691494439287c08ddb9b5793da605ee80299dd31e95fa3f323fac3c33d9d4"}, - {file = "regex-2025.9.18-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ef8d10cc0989565bcbe45fb4439f044594d5c2b8919d3d229ea2c4238f1d55b0"}, - {file = "regex-2025.9.18-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4baeb1b16735ac969a7eeecc216f1f8b7caf60431f38a2671ae601f716a32d25"}, - {file = "regex-2025.9.18-cp39-cp39-win32.whl", hash = "sha256:8e5f41ad24a1e0b5dfcf4c4e5d9f5bd54c895feb5708dd0c1d0d35693b24d478"}, - {file = "regex-2025.9.18-cp39-cp39-win_amd64.whl", hash = "sha256:50e8290707f2fb8e314ab3831e594da71e062f1d623b05266f8cfe4db4949afd"}, - {file = "regex-2025.9.18-cp39-cp39-win_arm64.whl", hash = "sha256:039a9d7195fd88c943d7c777d4941e8ef736731947becce773c31a1009cb3c35"}, - {file = "regex-2025.9.18.tar.gz", hash = "sha256:c5ba23274c61c6fef447ba6a39333297d0c247f53059dba0bca415cac511edc4"}, -] - -[[package]] -name = "repoze-sendmail" -version = "4.4.1" -description = "Repoze Sendmail" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "repoze.sendmail-4.4.1-py2.py3-none-any.whl", hash = "sha256:f1396893d3aa43502624e88941a441233c06679ae50b1966ffbfccba05da6347"}, - {file = "repoze.sendmail-4.4.1.tar.gz", hash = "sha256:7a8ea37914a5d38bad38052a83eac1d867b171ff4cc8b4d4994e892c05b0d424"}, -] - -[package.dependencies] -setuptools = "*" -transaction = "*" -"zope.interface" = ">=3.6.0" - -[package.extras] -docs = ["Sphinx", "repoze.sphinx.autointerface", "setuptools", "transaction", "zope.interface (>=3.6.0)"] -testing = ["coverage", "nose", "setuptools", "transaction", "zope.interface (>=3.6.0)"] - -[[package]] -name = "requests" -version = "2.32.5" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"}, - {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset_normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-oauthlib" -version = "2.0.0" -description = "OAuthlib authentication support for Requests." -optional = false -python-versions = ">=3.4" -groups = ["main"] -files = [ - {file = "requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9"}, - {file = "requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36"}, -] - -[package.dependencies] -oauthlib = ">=3.0.0" -requests = ">=2.0.0" - -[package.extras] -rsa = ["oauthlib[signedtoken] (>=3.0.0)"] - -[[package]] -name = "safetensors" -version = "0.6.2" -description = "" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "safetensors-0.6.2-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:9c85ede8ec58f120bad982ec47746981e210492a6db876882aa021446af8ffba"}, - {file = "safetensors-0.6.2-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d6675cf4b39c98dbd7d940598028f3742e0375a6b4d4277e76beb0c35f4b843b"}, - {file = "safetensors-0.6.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d2d2b3ce1e2509c68932ca03ab8f20570920cd9754b05063d4368ee52833ecd"}, - {file = "safetensors-0.6.2-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:93de35a18f46b0f5a6a1f9e26d91b442094f2df02e9fd7acf224cfec4238821a"}, - {file = "safetensors-0.6.2-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:89a89b505f335640f9120fac65ddeb83e40f1fd081cb8ed88b505bdccec8d0a1"}, - {file = "safetensors-0.6.2-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fc4d0d0b937e04bdf2ae6f70cd3ad51328635fe0e6214aa1fc811f3b576b3bda"}, - {file = "safetensors-0.6.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8045db2c872db8f4cbe3faa0495932d89c38c899c603f21e9b6486951a5ecb8f"}, - {file = "safetensors-0.6.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:81e67e8bab9878bb568cffbc5f5e655adb38d2418351dc0859ccac158f753e19"}, - {file = "safetensors-0.6.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b0e4d029ab0a0e0e4fdf142b194514695b1d7d3735503ba700cf36d0fc7136ce"}, - {file = "safetensors-0.6.2-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:fa48268185c52bfe8771e46325a1e21d317207bcabcb72e65c6e28e9ffeb29c7"}, - {file = "safetensors-0.6.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:d83c20c12c2d2f465997c51b7ecb00e407e5f94d7dec3ea0cc11d86f60d3fde5"}, - {file = "safetensors-0.6.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d944cea65fad0ead848b6ec2c37cc0b197194bec228f8020054742190e9312ac"}, - {file = "safetensors-0.6.2-cp38-abi3-win32.whl", hash = "sha256:cab75ca7c064d3911411461151cb69380c9225798a20e712b102edda2542ddb1"}, - {file = "safetensors-0.6.2-cp38-abi3-win_amd64.whl", hash = "sha256:c7b214870df923cbc1593c3faee16bec59ea462758699bd3fee399d00aac072c"}, - {file = "safetensors-0.6.2.tar.gz", hash = "sha256:43ff2aa0e6fa2dc3ea5524ac7ad93a9839256b8703761e76e2d0b2a3fa4f15d9"}, -] - -[package.extras] -all = ["safetensors[jax]", "safetensors[numpy]", "safetensors[paddlepaddle]", "safetensors[pinned-tf]", "safetensors[quality]", "safetensors[testing]", "safetensors[torch]"] -dev = ["safetensors[all]"] -jax = ["flax (>=0.6.3)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)", "safetensors[numpy]"] -mlx = ["mlx (>=0.0.9)"] -numpy = ["numpy (>=1.21.6)"] -paddlepaddle = ["paddlepaddle (>=2.4.1)", "safetensors[numpy]"] -pinned-tf = ["safetensors[numpy]", "tensorflow (==2.18.0)"] -quality = ["ruff"] -tensorflow = ["safetensors[numpy]", "tensorflow (>=2.11.0)"] -testing = ["h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "hypothesis (>=6.70.2)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "safetensors[numpy]", "setuptools-rust (>=1.5.2)"] -testingfree = ["huggingface-hub (>=0.12.1)", "hypothesis (>=6.70.2)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "safetensors[numpy]", "setuptools-rust (>=1.5.2)"] -torch = ["safetensors[numpy]", "torch (>=1.10)"] - -[[package]] -name = "scikit-image" -version = "0.25.2" -description = "Image processing in Python" -optional = false -python-versions = ">=3.10" -groups = ["main"] -files = [ - {file = "scikit_image-0.25.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d3278f586793176599df6a4cf48cb6beadae35c31e58dc01a98023af3dc31c78"}, - {file = "scikit_image-0.25.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:5c311069899ce757d7dbf1d03e32acb38bb06153236ae77fcd820fd62044c063"}, - {file = "scikit_image-0.25.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be455aa7039a6afa54e84f9e38293733a2622b8c2fb3362b822d459cc5605e99"}, - {file = "scikit_image-0.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4c464b90e978d137330be433df4e76d92ad3c5f46a22f159520ce0fdbea8a09"}, - {file = "scikit_image-0.25.2-cp310-cp310-win_amd64.whl", hash = "sha256:60516257c5a2d2f74387c502aa2f15a0ef3498fbeaa749f730ab18f0a40fd054"}, - {file = "scikit_image-0.25.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f4bac9196fb80d37567316581c6060763b0f4893d3aca34a9ede3825bc035b17"}, - {file = "scikit_image-0.25.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d989d64ff92e0c6c0f2018c7495a5b20e2451839299a018e0e5108b2680f71e0"}, - {file = "scikit_image-0.25.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2cfc96b27afe9a05bc92f8c6235321d3a66499995675b27415e0d0c76625173"}, - {file = "scikit_image-0.25.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24cc986e1f4187a12aa319f777b36008764e856e5013666a4a83f8df083c2641"}, - {file = "scikit_image-0.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:b4f6b61fc2db6340696afe3db6b26e0356911529f5f6aee8c322aa5157490c9b"}, - {file = "scikit_image-0.25.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8db8dd03663112783221bf01ccfc9512d1cc50ac9b5b0fe8f4023967564719fb"}, - {file = "scikit_image-0.25.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:483bd8cc10c3d8a7a37fae36dfa5b21e239bd4ee121d91cad1f81bba10cfb0ed"}, - {file = "scikit_image-0.25.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d1e80107bcf2bf1291acfc0bf0425dceb8890abe9f38d8e94e23497cbf7ee0d"}, - {file = "scikit_image-0.25.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a17e17eb8562660cc0d31bb55643a4da996a81944b82c54805c91b3fe66f4824"}, - {file = "scikit_image-0.25.2-cp312-cp312-win_amd64.whl", hash = "sha256:bdd2b8c1de0849964dbc54037f36b4e9420157e67e45a8709a80d727f52c7da2"}, - {file = "scikit_image-0.25.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7efa888130f6c548ec0439b1a7ed7295bc10105458a421e9bf739b457730b6da"}, - {file = "scikit_image-0.25.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:dd8011efe69c3641920614d550f5505f83658fe33581e49bed86feab43a180fc"}, - {file = "scikit_image-0.25.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28182a9d3e2ce3c2e251383bdda68f8d88d9fff1a3ebe1eb61206595c9773341"}, - {file = "scikit_image-0.25.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8abd3c805ce6944b941cfed0406d88faeb19bab3ed3d4b50187af55cf24d147"}, - {file = "scikit_image-0.25.2-cp313-cp313-win_amd64.whl", hash = "sha256:64785a8acefee460ec49a354706db0b09d1f325674107d7fa3eadb663fb56d6f"}, - {file = "scikit_image-0.25.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:330d061bd107d12f8d68f1d611ae27b3b813b8cdb0300a71d07b1379178dd4cd"}, - {file = "scikit_image-0.25.2.tar.gz", hash = "sha256:e5a37e6cd4d0c018a7a55b9d601357e3382826d3888c10d0213fc63bff977dde"}, -] - -[package.dependencies] -imageio = ">=2.33,<2.35.0 || >2.35.0" -lazy-loader = ">=0.4" -networkx = ">=3.0" -numpy = ">=1.24" -packaging = ">=21" -pillow = ">=10.1" -scipy = ">=1.11.4" -tifffile = ">=2022.8.12" - -[package.extras] -build = ["Cython (>=3.0.8)", "build (>=1.2.1)", "meson-python (>=0.16)", "ninja (>=1.11.1.1)", "numpy (>=2.0)", "pythran (>=0.16)", "spin (==0.13)"] -data = ["pooch (>=1.6.0)"] -developer = ["ipython", "pre-commit", "tomli ; python_version < \"3.11\""] -docs = ["PyWavelets (>=1.6)", "dask[array] (>=2023.2.0)", "intersphinx-registry (>=0.2411.14)", "ipykernel", "ipywidgets", "kaleido (==0.2.1)", "matplotlib (>=3.7)", "myst-parser", "numpydoc (>=1.7)", "pandas (>=2.0)", "plotly (>=5.20)", "pooch (>=1.6)", "pydata-sphinx-theme (>=0.16)", "pytest-doctestplus", "scikit-learn (>=1.2)", "seaborn (>=0.11)", "sphinx (>=8.0)", "sphinx-copybutton", "sphinx-gallery[parallel] (>=0.18)", "sphinx_design (>=0.5)", "tifffile (>=2022.8.12)"] -optional = ["PyWavelets (>=1.6)", "SimpleITK", "astropy (>=5.0)", "cloudpickle (>=1.1.1)", "dask[array] (>=2023.2.0)", "matplotlib (>=3.7)", "pooch (>=1.6.0)", "pyamg (>=5.2)", "scikit-learn (>=1.2)"] -test = ["asv", "numpydoc (>=1.7)", "pooch (>=1.6.0)", "pytest (>=8)", "pytest-cov (>=2.11.0)", "pytest-doctestplus", "pytest-faulthandler", "pytest-localserver"] - -[[package]] -name = "scipy" -version = "1.15.3" -description = "Fundamental algorithms for scientific computing in Python" -optional = false -python-versions = ">=3.10" -groups = ["main"] -markers = "python_version == \"3.10\"" -files = [ - {file = "scipy-1.15.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:a345928c86d535060c9c2b25e71e87c39ab2f22fc96e9636bd74d1dbf9de448c"}, - {file = "scipy-1.15.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ad3432cb0f9ed87477a8d97f03b763fd1d57709f1bbde3c9369b1dff5503b253"}, - {file = "scipy-1.15.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:aef683a9ae6eb00728a542b796f52a5477b78252edede72b8327a886ab63293f"}, - {file = "scipy-1.15.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:1c832e1bd78dea67d5c16f786681b28dd695a8cb1fb90af2e27580d3d0967e92"}, - {file = "scipy-1.15.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:263961f658ce2165bbd7b99fa5135195c3a12d9bef045345016b8b50c315cb82"}, - {file = "scipy-1.15.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2abc762b0811e09a0d3258abee2d98e0c703eee49464ce0069590846f31d40"}, - {file = "scipy-1.15.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed7284b21a7a0c8f1b6e5977ac05396c0d008b89e05498c8b7e8f4a1423bba0e"}, - {file = "scipy-1.15.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5380741e53df2c566f4d234b100a484b420af85deb39ea35a1cc1be84ff53a5c"}, - {file = "scipy-1.15.3-cp310-cp310-win_amd64.whl", hash = "sha256:9d61e97b186a57350f6d6fd72640f9e99d5a4a2b8fbf4b9ee9a841eab327dc13"}, - {file = "scipy-1.15.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:993439ce220d25e3696d1b23b233dd010169b62f6456488567e830654ee37a6b"}, - {file = "scipy-1.15.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:34716e281f181a02341ddeaad584205bd2fd3c242063bd3423d61ac259ca7eba"}, - {file = "scipy-1.15.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3b0334816afb8b91dab859281b1b9786934392aa3d527cd847e41bb6f45bee65"}, - {file = "scipy-1.15.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:6db907c7368e3092e24919b5e31c76998b0ce1684d51a90943cb0ed1b4ffd6c1"}, - {file = "scipy-1.15.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:721d6b4ef5dc82ca8968c25b111e307083d7ca9091bc38163fb89243e85e3889"}, - {file = "scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39cb9c62e471b1bb3750066ecc3a3f3052b37751c7c3dfd0fd7e48900ed52982"}, - {file = "scipy-1.15.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:795c46999bae845966368a3c013e0e00947932d68e235702b5c3f6ea799aa8c9"}, - {file = "scipy-1.15.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:18aaacb735ab38b38db42cb01f6b92a2d0d4b6aabefeb07f02849e47f8fb3594"}, - {file = "scipy-1.15.3-cp311-cp311-win_amd64.whl", hash = "sha256:ae48a786a28412d744c62fd7816a4118ef97e5be0bee968ce8f0a2fba7acf3bb"}, - {file = "scipy-1.15.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6ac6310fdbfb7aa6612408bd2f07295bcbd3fda00d2d702178434751fe48e019"}, - {file = "scipy-1.15.3-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:185cd3d6d05ca4b44a8f1595af87f9c372bb6acf9c808e99aa3e9aa03bd98cf6"}, - {file = "scipy-1.15.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:05dc6abcd105e1a29f95eada46d4a3f251743cfd7d3ae8ddb4088047f24ea477"}, - {file = "scipy-1.15.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:06efcba926324df1696931a57a176c80848ccd67ce6ad020c810736bfd58eb1c"}, - {file = "scipy-1.15.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05045d8b9bfd807ee1b9f38761993297b10b245f012b11b13b91ba8945f7e45"}, - {file = "scipy-1.15.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271e3713e645149ea5ea3e97b57fdab61ce61333f97cfae392c28ba786f9bb49"}, - {file = "scipy-1.15.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6cfd56fc1a8e53f6e89ba3a7a7251f7396412d655bca2aa5611c8ec9a6784a1e"}, - {file = "scipy-1.15.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ff17c0bb1cb32952c09217d8d1eed9b53d1463e5f1dd6052c7857f83127d539"}, - {file = "scipy-1.15.3-cp312-cp312-win_amd64.whl", hash = "sha256:52092bc0472cfd17df49ff17e70624345efece4e1a12b23783a1ac59a1b728ed"}, - {file = "scipy-1.15.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c620736bcc334782e24d173c0fdbb7590a0a436d2fdf39310a8902505008759"}, - {file = "scipy-1.15.3-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:7e11270a000969409d37ed399585ee530b9ef6aa99d50c019de4cb01e8e54e62"}, - {file = "scipy-1.15.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8c9ed3ba2c8a2ce098163a9bdb26f891746d02136995df25227a20e71c396ebb"}, - {file = "scipy-1.15.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0bdd905264c0c9cfa74a4772cdb2070171790381a5c4d312c973382fc6eaf730"}, - {file = "scipy-1.15.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79167bba085c31f38603e11a267d862957cbb3ce018d8b38f79ac043bc92d825"}, - {file = "scipy-1.15.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9deabd6d547aee2c9a81dee6cc96c6d7e9a9b1953f74850c179f91fdc729cb7"}, - {file = "scipy-1.15.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dde4fc32993071ac0c7dd2d82569e544f0bdaff66269cb475e0f369adad13f11"}, - {file = "scipy-1.15.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f77f853d584e72e874d87357ad70f44b437331507d1c311457bed8ed2b956126"}, - {file = "scipy-1.15.3-cp313-cp313-win_amd64.whl", hash = "sha256:b90ab29d0c37ec9bf55424c064312930ca5f4bde15ee8619ee44e69319aab163"}, - {file = "scipy-1.15.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3ac07623267feb3ae308487c260ac684b32ea35fd81e12845039952f558047b8"}, - {file = "scipy-1.15.3-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6487aa99c2a3d509a5227d9a5e889ff05830a06b2ce08ec30df6d79db5fcd5c5"}, - {file = "scipy-1.15.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:50f9e62461c95d933d5c5ef4a1f2ebf9a2b4e83b0db374cb3f1de104d935922e"}, - {file = "scipy-1.15.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:14ed70039d182f411ffc74789a16df3835e05dc469b898233a245cdfd7f162cb"}, - {file = "scipy-1.15.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a769105537aa07a69468a0eefcd121be52006db61cdd8cac8a0e68980bbb723"}, - {file = "scipy-1.15.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db984639887e3dffb3928d118145ffe40eff2fa40cb241a306ec57c219ebbbb"}, - {file = "scipy-1.15.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:40e54d5c7e7ebf1aa596c374c49fa3135f04648a0caabcb66c52884b943f02b4"}, - {file = "scipy-1.15.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5e721fed53187e71d0ccf382b6bf977644c533e506c4d33c3fb24de89f5c3ed5"}, - {file = "scipy-1.15.3-cp313-cp313t-win_amd64.whl", hash = "sha256:76ad1fb5f8752eabf0fa02e4cc0336b4e8f021e2d5f061ed37d6d264db35e3ca"}, - {file = "scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf"}, -] - -[package.dependencies] -numpy = ">=1.23.5,<2.5" - -[package.extras] -dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] -doc = ["intersphinx_registry", "jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.19.1)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0,<8.0.0)", "sphinx-copybutton", "sphinx-design (>=0.4.0)"] -test = ["Cython", "array-api-strict (>=2.0,<2.1.1)", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja ; sys_platform != \"emscripten\"", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] - -[[package]] -name = "scipy" -version = "1.16.2" -description = "Fundamental algorithms for scientific computing in Python" -optional = false -python-versions = ">=3.11" -groups = ["main"] -markers = "python_version >= \"3.11\"" -files = [ - {file = "scipy-1.16.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:6ab88ea43a57da1af33292ebd04b417e8e2eaf9d5aa05700be8d6e1b6501cd92"}, - {file = "scipy-1.16.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c95e96c7305c96ede73a7389f46ccd6c659c4da5ef1b2789466baeaed3622b6e"}, - {file = "scipy-1.16.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:87eb178db04ece7c698220d523c170125dbffebb7af0345e66c3554f6f60c173"}, - {file = "scipy-1.16.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:4e409eac067dcee96a57fbcf424c13f428037827ec7ee3cb671ff525ca4fc34d"}, - {file = "scipy-1.16.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e574be127bb760f0dad24ff6e217c80213d153058372362ccb9555a10fc5e8d2"}, - {file = "scipy-1.16.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f5db5ba6188d698ba7abab982ad6973265b74bb40a1efe1821b58c87f73892b9"}, - {file = "scipy-1.16.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec6e74c4e884104ae006d34110677bfe0098203a3fec2f3faf349f4cb05165e3"}, - {file = "scipy-1.16.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:912f46667d2d3834bc3d57361f854226475f695eb08c08a904aadb1c936b6a88"}, - {file = "scipy-1.16.2-cp311-cp311-win_amd64.whl", hash = "sha256:91e9e8a37befa5a69e9cacbe0bcb79ae5afb4a0b130fd6db6ee6cc0d491695fa"}, - {file = "scipy-1.16.2-cp311-cp311-win_arm64.whl", hash = "sha256:f3bf75a6dcecab62afde4d1f973f1692be013110cad5338007927db8da73249c"}, - {file = "scipy-1.16.2-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:89d6c100fa5c48472047632e06f0876b3c4931aac1f4291afc81a3644316bb0d"}, - {file = "scipy-1.16.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:ca748936cd579d3f01928b30a17dc474550b01272d8046e3e1ee593f23620371"}, - {file = "scipy-1.16.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:fac4f8ce2ddb40e2e3d0f7ec36d2a1e7f92559a2471e59aec37bd8d9de01fec0"}, - {file = "scipy-1.16.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:033570f1dcefd79547a88e18bccacff025c8c647a330381064f561d43b821232"}, - {file = "scipy-1.16.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ea3421209bf00c8a5ef2227de496601087d8f638a2363ee09af059bd70976dc1"}, - {file = "scipy-1.16.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f66bd07ba6f84cd4a380b41d1bf3c59ea488b590a2ff96744845163309ee8e2f"}, - {file = "scipy-1.16.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e9feab931bd2aea4a23388c962df6468af3d808ddf2d40f94a81c5dc38f32ef"}, - {file = "scipy-1.16.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03dfc75e52f72cf23ec2ced468645321407faad8f0fe7b1f5b49264adbc29cb1"}, - {file = "scipy-1.16.2-cp312-cp312-win_amd64.whl", hash = "sha256:0ce54e07bbb394b417457409a64fd015be623f36e330ac49306433ffe04bc97e"}, - {file = "scipy-1.16.2-cp312-cp312-win_arm64.whl", hash = "sha256:2a8ffaa4ac0df81a0b94577b18ee079f13fecdb924df3328fc44a7dc5ac46851"}, - {file = "scipy-1.16.2-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:84f7bf944b43e20b8a894f5fe593976926744f6c185bacfcbdfbb62736b5cc70"}, - {file = "scipy-1.16.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5c39026d12edc826a1ef2ad35ad1e6d7f087f934bb868fc43fa3049c8b8508f9"}, - {file = "scipy-1.16.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e52729ffd45b68777c5319560014d6fd251294200625d9d70fd8626516fc49f5"}, - {file = "scipy-1.16.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:024dd4a118cccec09ca3209b7e8e614931a6ffb804b2a601839499cb88bdf925"}, - {file = "scipy-1.16.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7a5dc7ee9c33019973a470556081b0fd3c9f4c44019191039f9769183141a4d9"}, - {file = "scipy-1.16.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c2275ff105e508942f99d4e3bc56b6ef5e4b3c0af970386ca56b777608ce95b7"}, - {file = "scipy-1.16.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:af80196eaa84f033e48444d2e0786ec47d328ba00c71e4299b602235ffef9acb"}, - {file = "scipy-1.16.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9fb1eb735fe3d6ed1f89918224e3385fbf6f9e23757cacc35f9c78d3b712dd6e"}, - {file = "scipy-1.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:fda714cf45ba43c9d3bae8f2585c777f64e3f89a2e073b668b32ede412d8f52c"}, - {file = "scipy-1.16.2-cp313-cp313-win_arm64.whl", hash = "sha256:2f5350da923ccfd0b00e07c3e5cfb316c1c0d6c1d864c07a72d092e9f20db104"}, - {file = "scipy-1.16.2-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:53d8d2ee29b925344c13bda64ab51785f016b1b9617849dac10897f0701b20c1"}, - {file = "scipy-1.16.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:9e05e33657efb4c6a9d23bd8300101536abd99c85cca82da0bffff8d8764d08a"}, - {file = "scipy-1.16.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:7fe65b36036357003b3ef9d37547abeefaa353b237e989c21027b8ed62b12d4f"}, - {file = "scipy-1.16.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6406d2ac6d40b861cccf57f49592f9779071655e9f75cd4f977fa0bdd09cb2e4"}, - {file = "scipy-1.16.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff4dc42bd321991fbf611c23fc35912d690f731c9914bf3af8f417e64aca0f21"}, - {file = "scipy-1.16.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:654324826654d4d9133e10675325708fb954bc84dae6e9ad0a52e75c6b1a01d7"}, - {file = "scipy-1.16.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63870a84cd15c44e65220eaed2dac0e8f8b26bbb991456a033c1d9abfe8a94f8"}, - {file = "scipy-1.16.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:fa01f0f6a3050fa6a9771a95d5faccc8e2f5a92b4a2e5440a0fa7264a2398472"}, - {file = "scipy-1.16.2-cp313-cp313t-win_amd64.whl", hash = "sha256:116296e89fba96f76353a8579820c2512f6e55835d3fad7780fece04367de351"}, - {file = "scipy-1.16.2-cp313-cp313t-win_arm64.whl", hash = "sha256:98e22834650be81d42982360382b43b17f7ba95e0e6993e2a4f5b9ad9283a94d"}, - {file = "scipy-1.16.2-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:567e77755019bb7461513c87f02bb73fb65b11f049aaaa8ca17cfaa5a5c45d77"}, - {file = "scipy-1.16.2-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:17d9bb346194e8967296621208fcdfd39b55498ef7d2f376884d5ac47cec1a70"}, - {file = "scipy-1.16.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:0a17541827a9b78b777d33b623a6dcfe2ef4a25806204d08ead0768f4e529a88"}, - {file = "scipy-1.16.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:d7d4c6ba016ffc0f9568d012f5f1eb77ddd99412aea121e6fa8b4c3b7cbad91f"}, - {file = "scipy-1.16.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9702c4c023227785c779cba2e1d6f7635dbb5b2e0936cdd3a4ecb98d78fd41eb"}, - {file = "scipy-1.16.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d1cdf0ac28948d225decdefcc45ad7dd91716c29ab56ef32f8e0d50657dffcc7"}, - {file = "scipy-1.16.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:70327d6aa572a17c2941cdfb20673f82e536e91850a2e4cb0c5b858b690e1548"}, - {file = "scipy-1.16.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5221c0b2a4b58aa7c4ed0387d360fd90ee9086d383bb34d9f2789fafddc8a936"}, - {file = "scipy-1.16.2-cp314-cp314-win_amd64.whl", hash = "sha256:f5a85d7b2b708025af08f060a496dd261055b617d776fc05a1a1cc69e09fe9ff"}, - {file = "scipy-1.16.2-cp314-cp314-win_arm64.whl", hash = "sha256:2cc73a33305b4b24556957d5857d6253ce1e2dcd67fa0ff46d87d1670b3e1e1d"}, - {file = "scipy-1.16.2-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:9ea2a3fed83065d77367775d689401a703d0f697420719ee10c0780bcab594d8"}, - {file = "scipy-1.16.2-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7280d926f11ca945c3ef92ba960fa924e1465f8d07ce3a9923080363390624c4"}, - {file = "scipy-1.16.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:8afae1756f6a1fe04636407ef7dbece33d826a5d462b74f3d0eb82deabefd831"}, - {file = "scipy-1.16.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:5c66511f29aa8d233388e7416a3f20d5cae7a2744d5cee2ecd38c081f4e861b3"}, - {file = "scipy-1.16.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efe6305aeaa0e96b0ccca5ff647a43737d9a092064a3894e46c414db84bc54ac"}, - {file = "scipy-1.16.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f3a337d9ae06a1e8d655ee9d8ecb835ea5ddcdcbd8d23012afa055ab014f374"}, - {file = "scipy-1.16.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bab3605795d269067d8ce78a910220262711b753de8913d3deeaedb5dded3bb6"}, - {file = "scipy-1.16.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b0348d8ddb55be2a844c518cd8cc8deeeb8aeba707cf834db5758fc89b476a2c"}, - {file = "scipy-1.16.2-cp314-cp314t-win_amd64.whl", hash = "sha256:26284797e38b8a75e14ea6631d29bda11e76ceaa6ddb6fdebbfe4c4d90faf2f9"}, - {file = "scipy-1.16.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d2a4472c231328d4de38d5f1f68fdd6d28a615138f842580a8a321b5845cf779"}, - {file = "scipy-1.16.2.tar.gz", hash = "sha256:af029b153d243a80afb6eabe40b0a07f8e35c9adc269c019f364ad747f826a6b"}, -] - -[package.dependencies] -numpy = ">=1.25.2,<2.6" - -[package.extras] -dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] -doc = ["intersphinx_registry", "jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.19.1)", "jupytext", "linkify-it-py", "matplotlib (>=3.5)", "myst-nb (>=1.2.0)", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0,<8.2.0)", "sphinx-copybutton", "sphinx-design (>=0.4.0)"] -test = ["Cython", "array-api-strict (>=2.3.1)", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja ; sys_platform != \"emscripten\"", "pooch", "pytest (>=8.0.0)", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] - -[[package]] -name = "sentencepiece" -version = "0.2.1" -description = "Unsupervised text tokenizer and detokenizer." -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "sentencepiece-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e10fa50bdbaa5e2445dbd387979980d391760faf0ec99a09bd7780ff37eaec44"}, - {file = "sentencepiece-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f27ae6deea72efdb6f361750c92f6c21fd0ad087445082770cc34015213c526"}, - {file = "sentencepiece-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:60937c959e6f44159fdd9f56fbdd302501f96114a5ba436829496d5f32d8de3f"}, - {file = "sentencepiece-0.2.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8b1d91545578852f128650b8cce4ec20f93d39b378ff554ebe66290f2dabb92"}, - {file = "sentencepiece-0.2.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:27e38eee653abc3d387862e67bc5c8b6f428cd604e688b85d29170b7e725c26c"}, - {file = "sentencepiece-0.2.1-cp310-cp310-win32.whl", hash = "sha256:251874d720ac7f28024a168501f3c7bb15d1802245f6e66de565f18bbb9b5eaa"}, - {file = "sentencepiece-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:e52144670738b4b477fade6c2a9b6af71a8d0094514c9853ac9f6fc1fcfabae7"}, - {file = "sentencepiece-0.2.1-cp310-cp310-win_arm64.whl", hash = "sha256:9076430ac25dfa7147d9d05751dbc66a04bc1aaac371c07f84952979ea59f0d0"}, - {file = "sentencepiece-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6356d0986b8b8dc351b943150fcd81a1c6e6e4d439772e8584c64230e58ca987"}, - {file = "sentencepiece-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8f8ba89a3acb3dc1ae90f65ec1894b0b9596fdb98ab003ff38e058f898b39bc7"}, - {file = "sentencepiece-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:02593eca45440ef39247cee8c47322a34bdcc1d8ae83ad28ba5a899a2cf8d79a"}, - {file = "sentencepiece-0.2.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a0d15781a171d188b661ae4bde1d998c303f6bd8621498c50c671bd45a4798e"}, - {file = "sentencepiece-0.2.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f5a3e0d9f445ed9d66c0fec47d4b23d12cfc858b407a03c194c1b26c2ac2a63"}, - {file = "sentencepiece-0.2.1-cp311-cp311-win32.whl", hash = "sha256:6d297a1748d429ba8534eebe5535448d78b8acc32d00a29b49acf28102eeb094"}, - {file = "sentencepiece-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:82d9ead6591015f009cb1be1cb1c015d5e6f04046dbb8c9588b931e869a29728"}, - {file = "sentencepiece-0.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:39f8651bd10974eafb9834ce30d9bcf5b73e1fc798a7f7d2528f9820ca86e119"}, - {file = "sentencepiece-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:57cae326c8727de58c85977b175af132a7138d84c764635d7e71bbee7e774133"}, - {file = "sentencepiece-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:56dd39a3c4d6493db3cdca7e8cc68c6b633f0d4195495cbadfcf5af8a22d05a6"}, - {file = "sentencepiece-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d9381351182ff9888cc80e41c632e7e274b106f450de33d67a9e8f6043da6f76"}, - {file = "sentencepiece-0.2.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99f955df238021bf11f0fc37cdb54fd5e5b5f7fd30ecc3d93fb48b6815437167"}, - {file = "sentencepiece-0.2.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0cdfecef430d985f1c2bcbfff3defd1d95dae876fbd0173376012d2d7d24044b"}, - {file = "sentencepiece-0.2.1-cp312-cp312-win32.whl", hash = "sha256:a483fd29a34c3e34c39ac5556b0a90942bec253d260235729e50976f5dba1068"}, - {file = "sentencepiece-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:4cdc7c36234fda305e85c32949c5211faaf8dd886096c7cea289ddc12a2d02de"}, - {file = "sentencepiece-0.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:daeb5e9e9fcad012324807856113708614d534f596d5008638eb9b40112cd9e4"}, - {file = "sentencepiece-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dcd8161eee7b41aae57ded06272905dbd680a0a04b91edd0f64790c796b2f706"}, - {file = "sentencepiece-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c6c8f42949f419ff8c7e9960dbadcfbc982d7b5efc2f6748210d3dd53a7de062"}, - {file = "sentencepiece-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:097f3394e99456e9e4efba1737c3749d7e23563dd1588ce71a3d007f25475fff"}, - {file = "sentencepiece-0.2.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d7b670879c370d350557edabadbad1f6561a9e6968126e6debca4029e5547820"}, - {file = "sentencepiece-0.2.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7f0fd2f2693309e6628aeeb2e2faf6edd221134dfccac3308ca0de01f8dab47"}, - {file = "sentencepiece-0.2.1-cp313-cp313-win32.whl", hash = "sha256:92b3816aa2339355fda2c8c4e021a5de92180b00aaccaf5e2808972e77a4b22f"}, - {file = "sentencepiece-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:10ed3dab2044c47f7a2e7b4969b0c430420cdd45735d78c8f853191fa0e3148b"}, - {file = "sentencepiece-0.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac650534e2251083c5f75dde4ff28896ce7c8904133dc8fef42780f4d5588fcd"}, - {file = "sentencepiece-0.2.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:8dd4b477a7b069648d19363aad0cab9bad2f4e83b2d179be668efa672500dc94"}, - {file = "sentencepiece-0.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0c0f672da370cc490e4c59d89e12289778310a0e71d176c541e4834759e1ae07"}, - {file = "sentencepiece-0.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad8493bea8432dae8d6830365352350f3b4144415a1d09c4c8cb8d30cf3b6c3c"}, - {file = "sentencepiece-0.2.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b81a24733726e3678d2db63619acc5a8dccd074f7aa7a54ecd5ca33ca6d2d596"}, - {file = "sentencepiece-0.2.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0a81799d0a68d618e89063fb423c3001a034c893069135ffe51fee439ae474d6"}, - {file = "sentencepiece-0.2.1-cp313-cp313t-win32.whl", hash = "sha256:89a3ea015517c42c0341d0d962f3e6aaf2cf10d71b1932d475c44ba48d00aa2b"}, - {file = "sentencepiece-0.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:33f068c9382dc2e7c228eedfd8163b52baa86bb92f50d0488bf2b7da7032e484"}, - {file = "sentencepiece-0.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:b3616ad246f360e52c85781e47682d31abfb6554c779e42b65333d4b5f44ecc0"}, - {file = "sentencepiece-0.2.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:5d0350b686c320068702116276cfb26c066dc7e65cfef173980b11bb4d606719"}, - {file = "sentencepiece-0.2.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c7f54a31cde6fa5cb030370566f68152a742f433f8d2be458463d06c208aef33"}, - {file = "sentencepiece-0.2.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c83b85ab2d6576607f31df77ff86f28182be4a8de6d175d2c33ca609925f5da1"}, - {file = "sentencepiece-0.2.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1855f57db07b51fb51ed6c9c452f570624d2b169b36f0f79ef71a6e6c618cd8b"}, - {file = "sentencepiece-0.2.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01e6912125cb45d3792f530a4d38f8e21bf884d6b4d4ade1b2de5cf7a8d2a52b"}, - {file = "sentencepiece-0.2.1-cp314-cp314-win32.whl", hash = "sha256:c415c9de1447e0a74ae3fdb2e52f967cb544113a3a5ce3a194df185cbc1f962f"}, - {file = "sentencepiece-0.2.1-cp314-cp314-win_amd64.whl", hash = "sha256:881b2e44b14fc19feade3cbed314be37de639fc415375cefaa5bc81a4be137fd"}, - {file = "sentencepiece-0.2.1-cp314-cp314-win_arm64.whl", hash = "sha256:2005242a16d2dc3ac5fe18aa7667549134d37854823df4c4db244752453b78a8"}, - {file = "sentencepiece-0.2.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:a19adcec27c524cb7069a1c741060add95f942d1cbf7ad0d104dffa0a7d28a2b"}, - {file = "sentencepiece-0.2.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e37e4b4c4a11662b5db521def4e44d4d30ae69a1743241412a93ae40fdcab4bb"}, - {file = "sentencepiece-0.2.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:477c81505db072b3ab627e7eab972ea1025331bd3a92bacbf798df2b75ea86ec"}, - {file = "sentencepiece-0.2.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:010f025a544ef770bb395091d57cb94deb9652d8972e0d09f71d85d5a0816c8c"}, - {file = "sentencepiece-0.2.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:733e59ff1794d26db706cd41fc2d7ca5f6c64a820709cb801dc0ea31780d64ab"}, - {file = "sentencepiece-0.2.1-cp314-cp314t-win32.whl", hash = "sha256:d3233770f78e637dc8b1fda2cd7c3b99ec77e7505041934188a4e7fe751de3b0"}, - {file = "sentencepiece-0.2.1-cp314-cp314t-win_amd64.whl", hash = "sha256:5e4366c97b68218fd30ea72d70c525e6e78a6c0a88650f57ac4c43c63b234a9d"}, - {file = "sentencepiece-0.2.1-cp314-cp314t-win_arm64.whl", hash = "sha256:105e36e75cbac1292642045458e8da677b2342dcd33df503e640f0b457cb6751"}, - {file = "sentencepiece-0.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:afefe50a0cdcb4f2fd9733cb52001a2c164181ee2d82c32d38f5b1b326a8528c"}, - {file = "sentencepiece-0.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:891ade6503dd93d418c03993f7d6a8aa20260c422cefff5096b9068185e67642"}, - {file = "sentencepiece-0.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:814978ac05130dd5812b4b03215c766bc6abaef13e7bd72bc534e4d1e12e9a4c"}, - {file = "sentencepiece-0.2.1-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:017f97b274d4b0baa84b2dc743bf4517be81156f413bb24f12aacacde378e5ab"}, - {file = "sentencepiece-0.2.1-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22c4ebcb3c6ab1496ab1c37c79ef7bb563b8726f29548c30773b7a4cb152df1a"}, - {file = "sentencepiece-0.2.1-cp39-cp39-win32.whl", hash = "sha256:caa4e560c72c151da80036aecc2159e51a7fd8ae9efebefd96860460ce6bd025"}, - {file = "sentencepiece-0.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:2af5a1fb05013332ad94343b8b5f3973e006a2dde2dfba55a819549e054e2f0f"}, - {file = "sentencepiece-0.2.1-cp39-cp39-win_arm64.whl", hash = "sha256:3d165fbb9bf8fba35f1946ba2617c3f9995679f07438325f07c026d53f33e746"}, - {file = "sentencepiece-0.2.1.tar.gz", hash = "sha256:8138cec27c2f2282f4a34d9a016e3374cd40e5c6e9cb335063db66a0a3b71fad"}, -] - -[package.extras] -test = ["pytest"] -testpaths = ["test"] - -[[package]] -name = "setuptools" -version = "80.9.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922"}, - {file = "setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""] -core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"] - -[[package]] -name = "six" -version = "1.17.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main"] -files = [ - {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, - {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, -] - -[[package]] -name = "sqlalchemy" -version = "2.0.44" -description = "Database Abstraction Library" -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "SQLAlchemy-2.0.44-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:471733aabb2e4848d609141a9e9d56a427c0a038f4abf65dd19d7a21fd563632"}, - {file = "SQLAlchemy-2.0.44-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48bf7d383a35e668b984c805470518b635d48b95a3c57cb03f37eaa3551b5f9f"}, - {file = "SQLAlchemy-2.0.44-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bf4bb6b3d6228fcf3a71b50231199fb94d2dd2611b66d33be0578ea3e6c2726"}, - {file = "SQLAlchemy-2.0.44-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:e998cf7c29473bd077704cea3577d23123094311f59bdc4af551923b168332b1"}, - {file = "SQLAlchemy-2.0.44-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:ebac3f0b5732014a126b43c2b7567f2f0e0afea7d9119a3378bde46d3dcad88e"}, - {file = "SQLAlchemy-2.0.44-cp37-cp37m-win32.whl", hash = "sha256:3255d821ee91bdf824795e936642bbf43a4c7cedf5d1aed8d24524e66843aa74"}, - {file = "SQLAlchemy-2.0.44-cp37-cp37m-win_amd64.whl", hash = "sha256:78e6c137ba35476adb5432103ae1534f2f5295605201d946a4198a0dea4b38e7"}, - {file = "sqlalchemy-2.0.44-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c77f3080674fc529b1bd99489378c7f63fcb4ba7f8322b79732e0258f0ea3ce"}, - {file = "sqlalchemy-2.0.44-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c26ef74ba842d61635b0152763d057c8d48215d5be9bb8b7604116a059e9985"}, - {file = "sqlalchemy-2.0.44-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4a172b31785e2f00780eccab00bc240ccdbfdb8345f1e6063175b3ff12ad1b0"}, - {file = "sqlalchemy-2.0.44-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9480c0740aabd8cb29c329b422fb65358049840b34aba0adf63162371d2a96e"}, - {file = "sqlalchemy-2.0.44-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:17835885016b9e4d0135720160db3095dc78c583e7b902b6be799fb21035e749"}, - {file = "sqlalchemy-2.0.44-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cbe4f85f50c656d753890f39468fcd8190c5f08282caf19219f684225bfd5fd2"}, - {file = "sqlalchemy-2.0.44-cp310-cp310-win32.whl", hash = "sha256:2fcc4901a86ed81dc76703f3b93ff881e08761c63263c46991081fd7f034b165"}, - {file = "sqlalchemy-2.0.44-cp310-cp310-win_amd64.whl", hash = "sha256:9919e77403a483ab81e3423151e8ffc9dd992c20d2603bf17e4a8161111e55f5"}, - {file = "sqlalchemy-2.0.44-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fe3917059c7ab2ee3f35e77757062b1bea10a0b6ca633c58391e3f3c6c488dd"}, - {file = "sqlalchemy-2.0.44-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:de4387a354ff230bc979b46b2207af841dc8bf29847b6c7dbe60af186d97aefa"}, - {file = "sqlalchemy-2.0.44-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3678a0fb72c8a6a29422b2732fe423db3ce119c34421b5f9955873eb9b62c1e"}, - {file = "sqlalchemy-2.0.44-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cf6872a23601672d61a68f390e44703442639a12ee9dd5a88bbce52a695e46e"}, - {file = "sqlalchemy-2.0.44-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:329aa42d1be9929603f406186630135be1e7a42569540577ba2c69952b7cf399"}, - {file = "sqlalchemy-2.0.44-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:70e03833faca7166e6a9927fbee7c27e6ecde436774cd0b24bbcc96353bce06b"}, - {file = "sqlalchemy-2.0.44-cp311-cp311-win32.whl", hash = "sha256:253e2f29843fb303eca6b2fc645aca91fa7aa0aa70b38b6950da92d44ff267f3"}, - {file = "sqlalchemy-2.0.44-cp311-cp311-win_amd64.whl", hash = "sha256:7a8694107eb4308a13b425ca8c0e67112f8134c846b6e1f722698708741215d5"}, - {file = "sqlalchemy-2.0.44-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72fea91746b5890f9e5e0997f16cbf3d53550580d76355ba2d998311b17b2250"}, - {file = "sqlalchemy-2.0.44-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:585c0c852a891450edbb1eaca8648408a3cc125f18cf433941fa6babcc359e29"}, - {file = "sqlalchemy-2.0.44-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b94843a102efa9ac68a7a30cd46df3ff1ed9c658100d30a725d10d9c60a2f44"}, - {file = "sqlalchemy-2.0.44-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:119dc41e7a7defcefc57189cfa0e61b1bf9c228211aba432b53fb71ef367fda1"}, - {file = "sqlalchemy-2.0.44-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0765e318ee9179b3718c4fd7ba35c434f4dd20332fbc6857a5e8df17719c24d7"}, - {file = "sqlalchemy-2.0.44-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2e7b5b079055e02d06a4308d0481658e4f06bc7ef211567edc8f7d5dce52018d"}, - {file = "sqlalchemy-2.0.44-cp312-cp312-win32.whl", hash = "sha256:846541e58b9a81cce7dee8329f352c318de25aa2f2bbe1e31587eb1f057448b4"}, - {file = "sqlalchemy-2.0.44-cp312-cp312-win_amd64.whl", hash = "sha256:7cbcb47fd66ab294703e1644f78971f6f2f1126424d2b300678f419aa73c7b6e"}, - {file = "sqlalchemy-2.0.44-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ff486e183d151e51b1d694c7aa1695747599bb00b9f5f604092b54b74c64a8e1"}, - {file = "sqlalchemy-2.0.44-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b1af8392eb27b372ddb783b317dea0f650241cea5bd29199b22235299ca2e45"}, - {file = "sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b61188657e3a2b9ac4e8f04d6cf8e51046e28175f79464c67f2fd35bceb0976"}, - {file = "sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b87e7b91a5d5973dda5f00cd61ef72ad75a1db73a386b62877d4875a8840959c"}, - {file = "sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:15f3326f7f0b2bfe406ee562e17f43f36e16167af99c4c0df61db668de20002d"}, - {file = "sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e77faf6ff919aa8cd63f1c4e561cac1d9a454a191bb864d5dd5e545935e5a40"}, - {file = "sqlalchemy-2.0.44-cp313-cp313-win32.whl", hash = "sha256:ee51625c2d51f8baadf2829fae817ad0b66b140573939dd69284d2ba3553ae73"}, - {file = "sqlalchemy-2.0.44-cp313-cp313-win_amd64.whl", hash = "sha256:c1c80faaee1a6c3428cecf40d16a2365bcf56c424c92c2b6f0f9ad204b899e9e"}, - {file = "sqlalchemy-2.0.44-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2fc44e5965ea46909a416fff0af48a219faefd5773ab79e5f8a5fcd5d62b2667"}, - {file = "sqlalchemy-2.0.44-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:dc8b3850d2a601ca2320d081874033684e246d28e1c5e89db0864077cfc8f5a9"}, - {file = "sqlalchemy-2.0.44-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d733dec0614bb8f4bcb7c8af88172b974f685a31dc3a65cca0527e3120de5606"}, - {file = "sqlalchemy-2.0.44-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22be14009339b8bc16d6b9dc8780bacaba3402aa7581658e246114abbd2236e3"}, - {file = "sqlalchemy-2.0.44-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:357bade0e46064f88f2c3a99808233e67b0051cdddf82992379559322dfeb183"}, - {file = "sqlalchemy-2.0.44-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4848395d932e93c1595e59a8672aa7400e8922c39bb9b0668ed99ac6fa867822"}, - {file = "sqlalchemy-2.0.44-cp38-cp38-win32.whl", hash = "sha256:2f19644f27c76f07e10603580a47278abb2a70311136a7f8fd27dc2e096b9013"}, - {file = "sqlalchemy-2.0.44-cp38-cp38-win_amd64.whl", hash = "sha256:1df4763760d1de0dfc8192cc96d8aa293eb1a44f8f7a5fbe74caf1b551905c5e"}, - {file = "sqlalchemy-2.0.44-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f7027414f2b88992877573ab780c19ecb54d3a536bef3397933573d6b5068be4"}, - {file = "sqlalchemy-2.0.44-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fe166c7d00912e8c10d3a9a0ce105569a31a3d0db1a6e82c4e0f4bf16d5eca9"}, - {file = "sqlalchemy-2.0.44-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3caef1ff89b1caefc28f0368b3bde21a7e3e630c2eddac16abd9e47bd27cc36a"}, - {file = "sqlalchemy-2.0.44-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc2856d24afa44295735e72f3c75d6ee7fdd4336d8d3a8f3d44de7aa6b766df2"}, - {file = "sqlalchemy-2.0.44-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:11bac86b0deada30b6b5f93382712ff0e911fe8d31cb9bf46e6b149ae175eff0"}, - {file = "sqlalchemy-2.0.44-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d18cd0e9a0f37c9f4088e50e3839fcb69a380a0ec957408e0b57cff08ee0a26"}, - {file = "sqlalchemy-2.0.44-cp39-cp39-win32.whl", hash = "sha256:9e9018544ab07614d591a26c1bd4293ddf40752cc435caf69196740516af7100"}, - {file = "sqlalchemy-2.0.44-cp39-cp39-win_amd64.whl", hash = "sha256:8e0e4e66fd80f277a8c3de016a81a554e76ccf6b8d881ee0b53200305a8433f6"}, - {file = "sqlalchemy-2.0.44-py3-none-any.whl", hash = "sha256:19de7ca1246fbef9f9d1bff8f1ab25641569df226364a0e40457dc5457c54b05"}, - {file = "sqlalchemy-2.0.44.tar.gz", hash = "sha256:0ae7454e1ab1d780aee69fd2aae7d6b8670a581d8847f2d1e0f7ddfbf47e5a22"}, -] - -[package.dependencies] -greenlet = {version = ">=1", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} -typing-extensions = ">=4.6.0" - -[package.extras] -aiomysql = ["aiomysql (>=0.2.0)", "greenlet (>=1)"] -aioodbc = ["aioodbc", "greenlet (>=1)"] -aiosqlite = ["aiosqlite", "greenlet (>=1)", "typing_extensions (!=3.10.0.1)"] -asyncio = ["greenlet (>=1)"] -asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (>=1)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10)"] -mssql = ["pyodbc"] -mssql-pymssql = ["pymssql"] -mssql-pyodbc = ["pyodbc"] -mypy = ["mypy (>=0.910)"] -mysql = ["mysqlclient (>=1.4.0)"] -mysql-connector = ["mysql-connector-python"] -oracle = ["cx_oracle (>=8)"] -oracle-oracledb = ["oracledb (>=1.0.1)"] -postgresql = ["psycopg2 (>=2.7)"] -postgresql-asyncpg = ["asyncpg", "greenlet (>=1)"] -postgresql-pg8000 = ["pg8000 (>=1.29.1)"] -postgresql-psycopg = ["psycopg (>=3.0.7)"] -postgresql-psycopg2binary = ["psycopg2-binary"] -postgresql-psycopg2cffi = ["psycopg2cffi"] -postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] -pymysql = ["pymysql"] -sqlcipher = ["sqlcipher3_binary"] - -[[package]] -name = "sympy" -version = "1.14.0" -description = "Computer algebra system (CAS) in Python" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5"}, - {file = "sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517"}, -] - -[package.dependencies] -mpmath = ">=1.1.0,<1.4" - -[package.extras] -dev = ["hypothesis (>=6.70.0)", "pytest (>=7.1.0)"] - -[[package]] -name = "tifffile" -version = "2025.5.10" -description = "Read and write TIFF files" -optional = false -python-versions = ">=3.10" -groups = ["main"] -markers = "python_version == \"3.10\"" -files = [ - {file = "tifffile-2025.5.10-py3-none-any.whl", hash = "sha256:e37147123c0542d67bc37ba5cdd67e12ea6fbe6e86c52bee037a9eb6a064e5ad"}, - {file = "tifffile-2025.5.10.tar.gz", hash = "sha256:018335d34283aa3fd8c263bae5c3c2b661ebc45548fde31504016fcae7bf1103"}, -] - -[package.dependencies] -numpy = "*" - -[package.extras] -all = ["defusedxml", "fsspec", "imagecodecs (>=2024.12.30)", "lxml", "matplotlib", "zarr (<3)"] -codecs = ["imagecodecs (>=2024.12.30)"] -plot = ["matplotlib"] -test = ["cmapfile", "czifile", "dask", "defusedxml", "fsspec", "imagecodecs", "lfdfiles", "lxml", "ndtiff", "oiffile", "psdtags", "pytest", "roifile", "xarray", "zarr (<3)"] -xml = ["defusedxml", "lxml"] -zarr = ["fsspec", "zarr (<3)"] - -[[package]] -name = "tifffile" -version = "2025.10.4" -description = "Read and write TIFF files" -optional = false -python-versions = ">=3.11" -groups = ["main"] -markers = "python_version >= \"3.11\"" -files = [ - {file = "tifffile-2025.10.4-py3-none-any.whl", hash = "sha256:7687d691e49026053181470cec70fa9250e3a586b2041041297e38b10bbd34e1"}, - {file = "tifffile-2025.10.4.tar.gz", hash = "sha256:2e437c16ab211be5bcdc79f71b4907359115f1f83b5d919e7c297c29725d3e38"}, -] - -[package.dependencies] -numpy = "*" - -[package.extras] -all = ["defusedxml", "fsspec", "imagecodecs (>=2024.12.30)", "kerchunk", "lxml", "matplotlib", "zarr (>=3.1.3)"] -codecs = ["imagecodecs (>=2024.12.30)"] -plot = ["matplotlib"] -test = ["cmapfile", "czifile", "dask", "defusedxml", "fsspec", "imagecodecs", "kerchunk", "lfdfiles", "lxml", "ndtiff", "oiffile", "psdtags", "pytest", "requests", "roifile", "xarray", "zarr (>=3.1.3)"] -xml = ["defusedxml", "lxml"] -zarr = ["fsspec", "kerchunk", "zarr (>=3.1.3)"] - -[[package]] -name = "timm" -version = "1.0.20" -description = "PyTorch Image Models" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "timm-1.0.20-py3-none-any.whl", hash = "sha256:f6e62f780358476691996c47aa49de87b95cc507edf923c3042f74a07e45b7fe"}, - {file = "timm-1.0.20.tar.gz", hash = "sha256:7468d32a410c359181c1ef961f49c7e213286e0c342bfb898b99534a4221fc54"}, -] - -[package.dependencies] -huggingface_hub = "*" -pyyaml = "*" -safetensors = "*" -torch = "*" -torchvision = "*" - -[[package]] -name = "tokenizers" -version = "0.21.4" -description = "" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "tokenizers-0.21.4-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:2ccc10a7c3bcefe0f242867dc914fc1226ee44321eb618cfe3019b5df3400133"}, - {file = "tokenizers-0.21.4-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:5e2f601a8e0cd5be5cc7506b20a79112370b9b3e9cb5f13f68ab11acd6ca7d60"}, - {file = "tokenizers-0.21.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39b376f5a1aee67b4d29032ee85511bbd1b99007ec735f7f35c8a2eb104eade5"}, - {file = "tokenizers-0.21.4-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2107ad649e2cda4488d41dfd031469e9da3fcbfd6183e74e4958fa729ffbf9c6"}, - {file = "tokenizers-0.21.4-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c73012da95afafdf235ba80047699df4384fdc481527448a078ffd00e45a7d9"}, - {file = "tokenizers-0.21.4-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f23186c40395fc390d27f519679a58023f368a0aad234af145e0f39ad1212732"}, - {file = "tokenizers-0.21.4-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc88bb34e23a54cc42713d6d98af5f1bf79c07653d24fe984d2d695ba2c922a2"}, - {file = "tokenizers-0.21.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51b7eabb104f46c1c50b486520555715457ae833d5aee9ff6ae853d1130506ff"}, - {file = "tokenizers-0.21.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:714b05b2e1af1288bd1bc56ce496c4cebb64a20d158ee802887757791191e6e2"}, - {file = "tokenizers-0.21.4-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:1340ff877ceedfa937544b7d79f5b7becf33a4cfb58f89b3b49927004ef66f78"}, - {file = "tokenizers-0.21.4-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:3c1f4317576e465ac9ef0d165b247825a2a4078bcd01cba6b54b867bdf9fdd8b"}, - {file = "tokenizers-0.21.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:c212aa4e45ec0bb5274b16b6f31dd3f1c41944025c2358faaa5782c754e84c24"}, - {file = "tokenizers-0.21.4-cp39-abi3-win32.whl", hash = "sha256:6c42a930bc5f4c47f4ea775c91de47d27910881902b0f20e4990ebe045a415d0"}, - {file = "tokenizers-0.21.4-cp39-abi3-win_amd64.whl", hash = "sha256:475d807a5c3eb72c59ad9b5fcdb254f6e17f53dfcbb9903233b0dfa9c943b597"}, - {file = "tokenizers-0.21.4.tar.gz", hash = "sha256:fa23f85fbc9a02ec5c6978da172cdcbac23498c3ca9f3645c5c68740ac007880"}, -] - -[package.dependencies] -huggingface-hub = ">=0.16.4,<1.0" - -[package.extras] -dev = ["tokenizers[testing]"] -docs = ["setuptools-rust", "sphinx", "sphinx-rtd-theme"] -testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests", "ruff"] - -[[package]] -name = "torch" -version = "2.8.0" -description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" -optional = false -python-versions = ">=3.9.0" -groups = ["main"] -files = [ - {file = "torch-2.8.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:0be92c08b44009d4131d1ff7a8060d10bafdb7ddcb7359ef8d8c5169007ea905"}, - {file = "torch-2.8.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:89aa9ee820bb39d4d72b794345cccef106b574508dd17dbec457949678c76011"}, - {file = "torch-2.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e8e5bf982e87e2b59d932769938b698858c64cc53753894be25629bdf5cf2f46"}, - {file = "torch-2.8.0-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:a3f16a58a9a800f589b26d47ee15aca3acf065546137fc2af039876135f4c760"}, - {file = "torch-2.8.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:220a06fd7af8b653c35d359dfe1aaf32f65aa85befa342629f716acb134b9710"}, - {file = "torch-2.8.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:c12fa219f51a933d5f80eeb3a7a5d0cbe9168c0a14bbb4055f1979431660879b"}, - {file = "torch-2.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:8c7ef765e27551b2fbfc0f41bcf270e1292d9bf79f8e0724848b1682be6e80aa"}, - {file = "torch-2.8.0-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:5ae0524688fb6707c57a530c2325e13bb0090b745ba7b4a2cd6a3ce262572916"}, - {file = "torch-2.8.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e2fab4153768d433f8ed9279c8133a114a034a61e77a3a104dcdf54388838705"}, - {file = "torch-2.8.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b2aca0939fb7e4d842561febbd4ffda67a8e958ff725c1c27e244e85e982173c"}, - {file = "torch-2.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:2f4ac52f0130275d7517b03a33d2493bab3693c83dcfadf4f81688ea82147d2e"}, - {file = "torch-2.8.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:619c2869db3ada2c0105487ba21b5008defcc472d23f8b80ed91ac4a380283b0"}, - {file = "torch-2.8.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:2b2f96814e0345f5a5aed9bf9734efa913678ed19caf6dc2cddb7930672d6128"}, - {file = "torch-2.8.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:65616ca8ec6f43245e1f5f296603e33923f4c30f93d65e103d9e50c25b35150b"}, - {file = "torch-2.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:659df54119ae03e83a800addc125856effda88b016dfc54d9f65215c3975be16"}, - {file = "torch-2.8.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:1a62a1ec4b0498930e2543535cf70b1bef8c777713de7ceb84cd79115f553767"}, - {file = "torch-2.8.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:83c13411a26fac3d101fe8035a6b0476ae606deb8688e904e796a3534c197def"}, - {file = "torch-2.8.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:8f0a9d617a66509ded240add3754e462430a6c1fc5589f86c17b433dd808f97a"}, - {file = "torch-2.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:a7242b86f42be98ac674b88a4988643b9bc6145437ec8f048fea23f72feb5eca"}, - {file = "torch-2.8.0-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:7b677e17f5a3e69fdef7eb3b9da72622f8d322692930297e4ccb52fefc6c8211"}, - {file = "torch-2.8.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:da6afa31c13b669d4ba49d8a2169f0db2c3ec6bec4af898aa714f401d4c38904"}, - {file = "torch-2.8.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:06fcee8000e5c62a9f3e52a688b9c5abb7c6228d0e56e3452983416025c41381"}, - {file = "torch-2.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:5128fe752a355d9308e56af1ad28b15266fe2da5948660fad44de9e3a9e36e8c"}, - {file = "torch-2.8.0-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:e9f071f5b52a9f6970dc8a919694b27a91ae9dc08898b2b988abbef5eddfd1ae"}, -] - -[package.dependencies] -filelock = "*" -fsspec = "*" -jinja2 = "*" -networkx = "*" -nvidia-cublas-cu12 = {version = "12.8.4.1", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cuda-cupti-cu12 = {version = "12.8.90", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cuda-nvrtc-cu12 = {version = "12.8.93", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cuda-runtime-cu12 = {version = "12.8.90", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cudnn-cu12 = {version = "9.10.2.21", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cufft-cu12 = {version = "11.3.3.83", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cufile-cu12 = {version = "1.13.1.3", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-curand-cu12 = {version = "10.3.9.90", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cusolver-cu12 = {version = "11.7.3.90", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cusparse-cu12 = {version = "12.5.8.93", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cusparselt-cu12 = {version = "0.7.1", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-nccl-cu12 = {version = "2.27.3", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-nvjitlink-cu12 = {version = "12.8.93", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-nvtx-cu12 = {version = "12.8.90", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -setuptools = {version = "*", markers = "python_version >= \"3.12\""} -sympy = ">=1.13.3" -triton = {version = "3.4.0", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -typing-extensions = ">=4.10.0" - -[package.extras] -opt-einsum = ["opt-einsum (>=3.3)"] -optree = ["optree (>=0.13.0)"] -pyyaml = ["pyyaml"] - -[[package]] -name = "torchvision" -version = "0.23.0" -description = "image and video datasets and models for torch deep learning" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "torchvision-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7266871daca00ad46d1c073e55d972179d12a58fa5c9adec9a3db9bbed71284a"}, - {file = "torchvision-0.23.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:31c583ba27426a3a04eca8c05450524105c1564db41be6632f7536ef405a6de2"}, - {file = "torchvision-0.23.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:3932bf67256f2d095ce90a9f826f6033694c818856f4bb26794cf2ce64253e53"}, - {file = "torchvision-0.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:83ee5bf827d61a8af14620c0a61d8608558638ac9c3bac8adb7b27138e2147d1"}, - {file = "torchvision-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:49aa20e21f0c2bd458c71d7b449776cbd5f16693dd5807195a820612b8a229b7"}, - {file = "torchvision-0.23.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:01dc33ee24c79148aee7cdbcf34ae8a3c9da1674a591e781577b716d233b1fa6"}, - {file = "torchvision-0.23.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:35c27941831b653f5101edfe62c03d196c13f32139310519e8228f35eae0e96a"}, - {file = "torchvision-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:09bfde260e7963a15b80c9e442faa9f021c7e7f877ac0a36ca6561b367185013"}, - {file = "torchvision-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e0e2c04a91403e8dd3af9756c6a024a1d9c0ed9c0d592a8314ded8f4fe30d440"}, - {file = "torchvision-0.23.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:6dd7c4d329a0e03157803031bc856220c6155ef08c26d4f5bbac938acecf0948"}, - {file = "torchvision-0.23.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4e7d31c43bc7cbecbb1a5652ac0106b436aa66e26437585fc2c4b2cf04d6014c"}, - {file = "torchvision-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2e45272abe7b8bf0d06c405e78521b5757be1bd0ed7e5cd78120f7fdd4cbf35"}, - {file = "torchvision-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1c37e325e09a184b730c3ef51424f383ec5745378dc0eca244520aca29722600"}, - {file = "torchvision-0.23.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:2f7fd6c15f3697e80627b77934f77705f3bc0e98278b989b2655de01f6903e1d"}, - {file = "torchvision-0.23.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:a76fafe113b2977be3a21bf78f115438c1f88631d7a87203acb3dd6ae55889e6"}, - {file = "torchvision-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:07d069cb29691ff566e3b7f11f20d91044f079e1dbdc9d72e0655899a9b06938"}, - {file = "torchvision-0.23.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:2df618e1143805a7673aaf82cb5720dd9112d4e771983156aaf2ffff692eebf9"}, - {file = "torchvision-0.23.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:2a3299d2b1d5a7aed2d3b6ffb69c672ca8830671967eb1cee1497bacd82fe47b"}, - {file = "torchvision-0.23.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:76bc4c0b63d5114aa81281390f8472a12a6a35ce9906e67ea6044e5af4cab60c"}, - {file = "torchvision-0.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b9e2dabf0da9c8aa9ea241afb63a8f3e98489e706b22ac3f30416a1be377153b"}, - {file = "torchvision-0.23.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b190db205f90206c230fc2f91cbdfd5733334babc0e0d19bddb90a40b8cf26c2"}, - {file = "torchvision-0.23.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6c74cbc1cbee26dd4f35f989cd80dccc40411f258dee476b29871dee4b483af0"}, - {file = "torchvision-0.23.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:a9e9d7552d34547b80843eaf64ab0737b19b2e8bec2514286b8cfd30861ca8b5"}, - {file = "torchvision-0.23.0-cp39-cp39-win_amd64.whl", hash = "sha256:dc7ce5accbbb8c9df9a79f8cef6a6df042f28e2250a6ae0d2ca70b06473fa03b"}, -] - -[package.dependencies] -numpy = "*" -pillow = ">=5.3.0,<8.3.dev0 || >=8.4.dev0" -torch = "2.8.0" - -[package.extras] -gdown = ["gdown (>=4.7.3)"] -scipy = ["scipy"] - -[[package]] -name = "tqdm" -version = "4.67.1" -description = "Fast, Extensible Progress Meter" -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, - {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] -discord = ["requests"] -notebook = ["ipywidgets (>=6)"] -slack = ["slack-sdk"] -telegram = ["requests"] - -[[package]] -name = "transaction" -version = "5.0" -description = "Transaction management for Python" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "transaction-5.0-py3-none-any.whl", hash = "sha256:b4c0b2d49a042d86235fa76531c3356b66d7635bb0e9f29ba2512915fc7b7a42"}, - {file = "transaction-5.0.tar.gz", hash = "sha256:106e7bd782bcc0cb5119fc9225b0c9a71dfc53adb938be905223adaef22b1174"}, -] - -[package.dependencies] -"zope.interface" = "*" - -[package.extras] -docs = ["Sphinx", "repoze.sphinx.autointerface"] -testing = ["coverage"] - -[[package]] -name = "transformers" -version = "4.52.4" -description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow" -optional = false -python-versions = ">=3.9.0" -groups = ["main"] -files = [ - {file = "transformers-4.52.4-py3-none-any.whl", hash = "sha256:203f5c19416d5877e36e88633943761719538a25d9775977a24fe77a1e5adfc7"}, - {file = "transformers-4.52.4.tar.gz", hash = "sha256:aff3764441c1adc192a08dba49740d3cbbcb72d850586075aed6bd89b98203e6"}, -] - -[package.dependencies] -filelock = "*" -huggingface-hub = ">=0.30.0,<1.0" -numpy = ">=1.17" -packaging = ">=20.0" -pyyaml = ">=5.1" -regex = "!=2019.12.17" -requests = "*" -safetensors = ">=0.4.3" -tokenizers = ">=0.21,<0.22" -tqdm = ">=4.27" - -[package.extras] -accelerate = ["accelerate (>=0.26.0)"] -all = ["Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.26.0)", "av", "codecarbon (>=2.8.1)", "flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1,<0.14.0)", "kernels (>=0.4.4,<0.5)", "librosa", "num2words", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "phonemizer", "protobuf", "pyctcdecode (>=0.4.0)", "ray[tune] (>=2.7.0)", "scipy (<1.13.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "tensorflow (>2.9,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timm (<=1.0.11)", "tokenizers (>=0.21,<0.22)", "torch (>=2.1,<2.7)", "torchaudio", "torchvision"] -audio = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] -benchmark = ["optimum-benchmark (>=0.3.0)"] -codecarbon = ["codecarbon (>=2.8.1)"] -deepspeed = ["accelerate (>=0.26.0)", "deepspeed (>=0.9.3)"] -deepspeed-testing = ["GitPython (<3.1.19)", "accelerate (>=0.26.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "deepspeed (>=0.9.3)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "nltk (<=3.8.1)", "optuna", "parameterized", "protobuf", "psutil", "pydantic", "pytest (>=7.2.0)", "pytest-asyncio", "pytest-order", "pytest-rerunfailures", "pytest-rich", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.11.2)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "timeout-decorator"] -dev = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.26.0)", "av", "beautifulsoup4", "codecarbon (>=2.8.1)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "flax (>=0.4.1,<=0.7.0)", "fugashi (>=1.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "kenlm", "keras-nlp (>=0.3.1,<0.14.0)", "kernels (>=0.4.4,<0.5)", "libcst", "librosa", "nltk (<=3.8.1)", "num2words", "onnxconverter-common", "optax (>=0.0.8,<=0.1.4)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0)", "pytest-asyncio", "pytest-order", "pytest-rerunfailures", "pytest-rich", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rich", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.11.2)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "scipy (<1.13.0)", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "tensorflow (>2.9,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "timm (<=1.0.11)", "tokenizers (>=0.21,<0.22)", "torch (>=2.1,<2.7)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] -dev-tensorflow = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "isort (>=5.5.4)", "kenlm", "keras-nlp (>=0.3.1,<0.14.0)", "libcst", "librosa", "nltk (<=3.8.1)", "onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0)", "pytest-asyncio", "pytest-order", "pytest-rerunfailures", "pytest-rich", "pytest-timeout", "pytest-xdist", "rich", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.11.2)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "tensorflow (>2.9,<2.16)", "tensorflow-text (<2.16)", "tf2onnx", "timeout-decorator", "tokenizers (>=0.21,<0.22)", "urllib3 (<2.0.0)"] -dev-torch = ["GitPython (<3.1.19)", "Pillow (>=10.0.1,<=15.0)", "accelerate (>=0.26.0)", "beautifulsoup4", "codecarbon (>=2.8.1)", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "fugashi (>=1.0)", "ipadic (>=1.0.0,<2.0)", "isort (>=5.5.4)", "kenlm", "kernels (>=0.4.4,<0.5)", "libcst", "librosa", "nltk (<=3.8.1)", "num2words", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "optuna", "parameterized", "phonemizer", "protobuf", "psutil", "pyctcdecode (>=0.4.0)", "pydantic", "pytest (>=7.2.0)", "pytest-asyncio", "pytest-order", "pytest-rerunfailures", "pytest-rich", "pytest-timeout", "pytest-xdist", "ray[tune] (>=2.7.0)", "rhoknp (>=1.1.0,<1.3.1)", "rich", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.11.2)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "scikit-learn", "sentencepiece (>=0.1.91,!=0.1.92)", "sigopt", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "tensorboard", "timeout-decorator", "timm (<=1.0.11)", "tokenizers (>=0.21,<0.22)", "torch (>=2.1,<2.7)", "torchaudio", "torchvision", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)", "urllib3 (<2.0.0)"] -flax = ["flax (>=0.4.1,<=0.7.0)", "jax (>=0.4.1,<=0.4.13)", "jaxlib (>=0.4.1,<=0.4.13)", "optax (>=0.0.8,<=0.1.4)", "scipy (<1.13.0)"] -flax-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] -ftfy = ["ftfy"] -hf-xet = ["hf-xet"] -hub-kernels = ["kernels (>=0.4.4,<0.5)"] -integrations = ["kernels (>=0.4.4,<0.5)", "optuna", "ray[tune] (>=2.7.0)", "sigopt"] -ja = ["fugashi (>=1.0)", "ipadic (>=1.0.0,<2.0)", "rhoknp (>=1.1.0,<1.3.1)", "sudachidict-core (>=20220729)", "sudachipy (>=0.6.6)", "unidic (>=1.0.2)", "unidic-lite (>=1.0.7)"] -modelcreation = ["cookiecutter (==1.7.3)"] -natten = ["natten (>=0.14.6,<0.15.0)"] -num2words = ["num2words"] -onnx = ["onnxconverter-common", "onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)", "tf2onnx"] -onnxruntime = ["onnxruntime (>=1.4.0)", "onnxruntime-tools (>=1.4.2)"] -optuna = ["optuna"] -quality = ["GitPython (<3.1.19)", "datasets (!=2.5.0)", "isort (>=5.5.4)", "libcst", "rich", "ruff (==0.11.2)", "urllib3 (<2.0.0)"] -ray = ["ray[tune] (>=2.7.0)"] -retrieval = ["datasets (!=2.5.0)", "faiss-cpu"] -ruff = ["ruff (==0.11.2)"] -sagemaker = ["sagemaker (>=2.31.0)"] -sentencepiece = ["protobuf", "sentencepiece (>=0.1.91,!=0.1.92)"] -serving = ["fastapi", "pydantic", "starlette", "uvicorn"] -sigopt = ["sigopt"] -sklearn = ["scikit-learn"] -speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] -testing = ["GitPython (<3.1.19)", "beautifulsoup4", "cookiecutter (==1.7.3)", "datasets (!=2.5.0)", "dill (<0.3.5)", "evaluate (>=0.2.0)", "faiss-cpu", "nltk (<=3.8.1)", "parameterized", "psutil", "pydantic", "pytest (>=7.2.0)", "pytest-asyncio", "pytest-order", "pytest-rerunfailures", "pytest-rich", "pytest-timeout", "pytest-xdist", "rjieba", "rouge-score (!=0.0.7,!=0.0.8,!=0.1,!=0.1.1)", "ruff (==0.11.2)", "sacrebleu (>=1.4.12,<2.0.0)", "sacremoses", "sentencepiece (>=0.1.91,!=0.1.92)", "tensorboard", "timeout-decorator"] -tf = ["keras-nlp (>=0.3.1,<0.14.0)", "onnxconverter-common", "tensorflow (>2.9,<2.16)", "tensorflow-text (<2.16)", "tf2onnx"] -tf-cpu = ["keras (>2.9,<2.16)", "keras-nlp (>=0.3.1,<0.14.0)", "onnxconverter-common", "tensorflow-cpu (>2.9,<2.16)", "tensorflow-probability (<0.24)", "tensorflow-text (<2.16)", "tf2onnx"] -tf-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)"] -tiktoken = ["blobfile", "tiktoken"] -timm = ["timm (<=1.0.11)"] -tokenizers = ["tokenizers (>=0.21,<0.22)"] -torch = ["accelerate (>=0.26.0)", "torch (>=2.1,<2.7)"] -torch-speech = ["kenlm", "librosa", "phonemizer", "pyctcdecode (>=0.4.0)", "torchaudio"] -torch-vision = ["Pillow (>=10.0.1,<=15.0)", "torchvision"] -torchhub = ["filelock", "huggingface-hub (>=0.30.0,<1.0)", "importlib-metadata", "numpy (>=1.17)", "packaging (>=20.0)", "protobuf", "regex (!=2019.12.17)", "requests", "sentencepiece (>=0.1.91,!=0.1.92)", "tokenizers (>=0.21,<0.22)", "torch (>=2.1,<2.7)", "tqdm (>=4.27)"] -video = ["av"] -vision = ["Pillow (>=10.0.1,<=15.0)"] - -[[package]] -name = "translationstring" -version = "1.4" -description = "Utility library for i18n relied on by various Repoze and Pyramid packages" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "translationstring-1.4-py2.py3-none-any.whl", hash = "sha256:5f4dc4d939573db851c8d840551e1a0fb27b946afe3b95aafc22577eed2d6262"}, - {file = "translationstring-1.4.tar.gz", hash = "sha256:bf947538d76e69ba12ab17283b10355a9ecfbc078e6123443f43f2107f6376f3"}, -] - -[package.extras] -docs = ["Sphinx (>=1.3.1)", "docutils", "pylons-sphinx-themes"] - -[[package]] -name = "triton" -version = "3.4.0" -description = "A language and compiler for custom Deep Learning operations" -optional = false -python-versions = "<3.14,>=3.9" -groups = ["main"] -markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\"" -files = [ - {file = "triton-3.4.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ff2785de9bc02f500e085420273bb5cc9c9bb767584a4aa28d6e360cec70128"}, - {file = "triton-3.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b70f5e6a41e52e48cfc087436c8a28c17ff98db369447bcaff3b887a3ab4467"}, - {file = "triton-3.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c1d84a5c0ec2c0f8e8a072d7fd150cab84a9c239eaddc6706c081bfae4eb04"}, - {file = "triton-3.4.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00be2964616f4c619193cb0d1b29a99bd4b001d7dc333816073f92cf2a8ccdeb"}, - {file = "triton-3.4.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7936b18a3499ed62059414d7df563e6c163c5e16c3773678a3ee3d417865035d"}, - {file = "triton-3.4.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:98e5c1442eaeabae2e2452ae765801bd53cd4ce873cab0d1bdd59a32ab2d9397"}, -] - -[package.dependencies] -setuptools = ">=40.8.0" - -[package.extras] -build = ["cmake (>=3.20,<4.0)", "lit"] -tests = ["autopep8", "isort", "llnl-hatchet", "numpy", "pytest", "pytest-forked", "pytest-xdist", "scipy (>=1.7.1)"] -tutorials = ["matplotlib", "pandas", "tabulate"] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -description = "Backported and Experimental Type Hints for Python 3.9+" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, - {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, -] - -[[package]] -name = "urllib3" -version = "2.5.0" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, - {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "velruse" -version = "1.1.1" -description = "Simplifying third-party authentication for web applications." -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "velruse-1.1.1.tar.gz", hash = "sha256:556032ad6b758eaf1f303645724cfb80dd911b156a8decbdeae4b6fbab31626e"}, -] - -[package.dependencies] -anykeystore = "*" -pyramid = "*" -python-openid = "*" -requests = "*" -requests-oauthlib = "*" - -[package.extras] -docs = ["Sphinx", "docutils"] -testing = ["nose", "selenium", "webtest"] - -[[package]] -name = "venusian" -version = "3.1.1" -description = "A library for deferring decorator actions" -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "venusian-3.1.1-py3-none-any.whl", hash = "sha256:0845808a985976acbceaa1fbb871c7fac4fb28ae75453232970e9c2c2866dbf4"}, - {file = "venusian-3.1.1.tar.gz", hash = "sha256:534fb3b355669283eb3954581931e5d1d071fce61d029d58f3219a5e3a6f0c41"}, -] - -[package.extras] -docs = ["Sphinx (>=4.3.2)", "pylons-sphinx-themes", "repoze.sphinx.autointerface", "sphinx-copybutton"] -testing = ["coverage", "pytest", "pytest-cov"] - -[[package]] -name = "wcwidth" -version = "0.2.14" -description = "Measures the displayed width of unicode strings in a terminal" -optional = false -python-versions = ">=3.6" -groups = ["main"] -files = [ - {file = "wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1"}, - {file = "wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605"}, -] - -[[package]] -name = "webob" -version = "1.8.9" -description = "WSGI request and response object" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main"] -files = [ - {file = "WebOb-1.8.9-py2.py3-none-any.whl", hash = "sha256:45e34c58ed0c7e2ecd238ffd34432487ff13d9ad459ddfd77895e67abba7c1f9"}, - {file = "webob-1.8.9.tar.gz", hash = "sha256:ad6078e2edb6766d1334ec3dee072ac6a7f95b1e32ce10def8ff7f0f02d56589"}, -] - -[package.extras] -docs = ["Sphinx (>=1.7.5)", "pylons-sphinx-themes"] -testing = ["coverage", "pytest (>=3.1.0)", "pytest-cov", "pytest-xdist"] - -[[package]] -name = "wtforms" -version = "3.2.1" -description = "Form validation and rendering for Python web development." -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "wtforms-3.2.1-py3-none-any.whl", hash = "sha256:583bad77ba1dd7286463f21e11aa3043ca4869d03575921d1a1698d0715e0fd4"}, - {file = "wtforms-3.2.1.tar.gz", hash = "sha256:df3e6b70f3192e92623128123ec8dca3067df9cfadd43d59681e210cfb8d4682"}, -] - -[package.dependencies] -markupsafe = "*" - -[package.extras] -email = ["email-validator"] - -[[package]] -name = "wtforms-recaptcha" -version = "0.3.2" -description = "Custom WTForms field that handles reCaptcha display and validation" -optional = false -python-versions = "*" -groups = ["main"] -files = [ - {file = "wtforms-recaptcha-0.3.2.tar.gz", hash = "sha256:b566bffea417b05beb3424ca777e8618beb25770ac237c37c0bf8dd1db0e8496"}, - {file = "wtforms_recaptcha-0.3.2-py2.py3-none-any.whl", hash = "sha256:a9ace04fd1a939325276794f1816a97ddd84ef1b11f3f328670f7341e4450cb3"}, -] - -[package.dependencies] -WTForms = ">=0.6.1" - -[[package]] -name = "zipp" -version = "3.23.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e"}, - {file = "zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] -type = ["pytest-mypy"] - -[[package]] -name = "zope-deprecation" -version = "6.0" -description = "Zope Deprecation Infrastructure" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "zope_deprecation-6.0-py3-none-any.whl", hash = "sha256:ff72d51c88b516b9ddf2cfb826381cc49f99a6a89b7d35c97faca7bee3b46da6"}, - {file = "zope_deprecation-6.0.tar.gz", hash = "sha256:18727ebda8e63a6d4bd28a290e8b46852e9f14473debb5cc40a0a2dccfadf15f"}, -] - -[package.dependencies] -setuptools = "*" - -[package.extras] -docs = ["Sphinx"] -test = ["zope.testrunner (>=6.4)"] - -[[package]] -name = "zope-interface" -version = "8.0.1" -description = "Interfaces for Python" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "zope_interface-8.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fd7195081b8637eeed8d73e4d183b07199a1dc738fb28b3de6666b1b55662570"}, - {file = "zope_interface-8.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f7c4bc4021108847bce763673ce70d0716b08dfc2ba9889e7bad46ac2b3bb924"}, - {file = "zope_interface-8.0.1-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:758803806b962f32c87b31bb18c298b022965ba34fe532163831cc39118c24ab"}, - {file = "zope_interface-8.0.1-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f8e88f35f86bbe8243cad4b2972deef0fdfca0a0723455abbebdc83bbab96b69"}, - {file = "zope_interface-8.0.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7844765695937d9b0d83211220b72e2cf6ac81a08608ad2b58f2c094af498d83"}, - {file = "zope_interface-8.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:64fa7b206dd9669f29d5c1241a768bebe8ab1e8a4b63ee16491f041e058c09d0"}, - {file = "zope_interface-8.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4bd01022d2e1bce4a4a4ed9549edb25393c92e607d7daa6deff843f1f68b479d"}, - {file = "zope_interface-8.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:29be8db8b712d94f1c05e24ea230a879271d787205ba1c9a6100d1d81f06c69a"}, - {file = "zope_interface-8.0.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:51ae1b856565b30455b7879fdf0a56a88763b401d3f814fa9f9542d7410dbd7e"}, - {file = "zope_interface-8.0.1-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d2e7596149cb1acd1d4d41b9f8fe2ffc0e9e29e2e91d026311814181d0d9efaf"}, - {file = "zope_interface-8.0.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b2737c11c34fb9128816759864752d007ec4f987b571c934c30723ed881a7a4f"}, - {file = "zope_interface-8.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:cf66e4bf731aa7e0ced855bb3670e8cda772f6515a475c6a107bad5cb6604103"}, - {file = "zope_interface-8.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:115f27c1cc95ce7a517d960ef381beedb0a7ce9489645e80b9ab3cbf8a78799c"}, - {file = "zope_interface-8.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af655c573b84e3cb6a4f6fd3fbe04e4dc91c63c6b6f99019b3713ef964e589bc"}, - {file = "zope_interface-8.0.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:23f82ef9b2d5370750cc1bf883c3b94c33d098ce08557922a3fbc7ff3b63dfe1"}, - {file = "zope_interface-8.0.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:35a1565d5244997f2e629c5c68715b3d9d9036e8df23c4068b08d9316dcb2822"}, - {file = "zope_interface-8.0.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:029ea1db7e855a475bf88d9910baab4e94d007a054810e9007ac037a91c67c6f"}, - {file = "zope_interface-8.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0beb3e7f7dc153944076fcaf717a935f68d39efa9fce96ec97bafcc0c2ea6cab"}, - {file = "zope_interface-8.0.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:c7cc027fc5c61c5d69e5080c30b66382f454f43dc379c463a38e78a9c6bab71a"}, - {file = "zope_interface-8.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fcf9097ff3003b7662299f1c25145e15260ec2a27f9a9e69461a585d79ca8552"}, - {file = "zope_interface-8.0.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6d965347dd1fb9e9a53aa852d4ded46b41ca670d517fd54e733a6b6a4d0561c2"}, - {file = "zope_interface-8.0.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9a3b8bb77a4b89427a87d1e9eb969ab05e38e6b4a338a9de10f6df23c33ec3c2"}, - {file = "zope_interface-8.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:87e6b089002c43231fb9afec89268391bcc7a3b66e76e269ffde19a8112fb8d5"}, - {file = "zope_interface-8.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:64a43f5280aa770cbafd0307cb3d1ff430e2a1001774e8ceb40787abe4bb6658"}, - {file = "zope_interface-8.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b84464a9fcf801289fa8b15bfc0829e7855d47fb4a8059555effc6f2d1d9a613"}, - {file = "zope_interface-8.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7b915cf7e747b5356d741be79a153aa9107e8923bc93bcd65fc873caf0fb5c50"}, - {file = "zope_interface-8.0.1-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:110c73ddf974b369ef3c6e7b0d87d44673cf4914eba3fe8a33bfb21c6c606ad8"}, - {file = "zope_interface-8.0.1-cp39-cp39-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9e9bdca901c1bcc34e438001718512c65b3b8924aabcd732b6e7a7f0cd715f17"}, - {file = "zope_interface-8.0.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bbd22d4801ad3e8ec704ba9e3e6a4ac2e875e4d77e363051ccb76153d24c5519"}, - {file = "zope_interface-8.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:a0016ca85f93b938824e2f9a43534446e95134a2945b084944786e1ace2020bc"}, - {file = "zope_interface-8.0.1.tar.gz", hash = "sha256:eba5610d042c3704a48222f7f7c6ab5b243ed26f917e2bc69379456b115e02d1"}, -] - -[package.extras] -docs = ["Sphinx", "furo", "repoze.sphinx.autointerface"] -test = ["coverage[toml]", "zope.event", "zope.testing"] -testing = ["coverage[toml]", "zope.event", "zope.testing"] - -[[package]] -name = "zope-sqlalchemy" -version = "4.0" -description = "Minimal Zope/SQLAlchemy transaction integration" -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "zope_sqlalchemy-4.0-py3-none-any.whl", hash = "sha256:3fd2026271056818a04d3320e610525fd4773bc56300158411ed22909c72cd6e"}, - {file = "zope_sqlalchemy-4.0.tar.gz", hash = "sha256:d4aeb6d06aa7d0855d67fd3434b56674f01307c4cad50105c94bcfe391ee729d"}, -] - -[package.dependencies] -packaging = "*" -setuptools = "*" -SQLAlchemy = ">=1.1,<1.4.0 || >1.4.0,<1.4.1 || >1.4.1,<1.4.2 || >1.4.2,<1.4.3 || >1.4.3,<1.4.4 || >1.4.4,<1.4.5 || >1.4.5,<1.4.6 || >1.4.6,<2.0.32 || >2.0.32,<2.0.33 || >2.0.33,<2.0.34 || >2.0.34,<2.0.35 || >2.0.35" -transaction = ">=1.6.0" -"zope.interface" = ">=3.6.0" - -[package.extras] -test = ["zope.testing"] - -[metadata] -lock-version = "2.1" -python-versions = ">=3.10,<3.13" -content-hash = "57cba1eea087919b72ff239ae17308f92a333510085f18f5e31413d321f2458e" diff --git a/demo/Diffusion/pyproject.toml b/demo/Diffusion/pyproject.toml deleted file mode 100644 index 1b9dc1d15..000000000 --- a/demo/Diffusion/pyproject.toml +++ /dev/null @@ -1,115 +0,0 @@ -[project] -name = "tensorrt-diffusion" -version = "0.1.0" -description = "TensorRT-accelerated implementations of Stable Diffusion and other diffusion models" -readme = "README.md" -requires-python = ">=3.10,<3.13" - -# Core dependencies shared across all pipeline families -dependencies = [ - "apex==0.9.10dev", - "accelerate==1.2.1", - "colored==2.3.1", - "controlnet-aux==0.0.6", - "cuda-python==13.0.2", - "ftfy==6.3.1", - "matplotlib==3.10.7", - "nvtx==0.2.13", - "opencv-python-headless==4.8.0.74", - "scipy==1.15.3", - "transformers==4.52.4", - "onnx==1.19.0", - "onnxruntime==1.24.4; platform_machine == 'x86_64'", - "onnxruntime==1.22.1; platform_machine == 'aarch64'", - "onnx-graphsurgeon==0.5.2", - "peft==0.17.0", - "polygraphy==0.50.3", - "sentencepiece==0.2.1", - "numpy==1.26.4", - "nvidia-modelopt[torch,onnx]==0.40.0", -] - -[project.optional-dependencies] -# Stable Diffusion family (Stability AI) -# Pipelines: SD 1.4, SDXL, SD3, SD3.5, SVD (Stable Video Diffusion), Stable Cascade -sd = [ - "diffusers==0.37.1", - "onnxscript==0.5.4", - "imageio-ffmpeg", -] - -# Flux family (Black Forest Labs) -# Pipelines: Flux.1-dev, Flux.1-schnell, Flux.1-Canny, Flux.1-Depth, Flux.1-Kontext -# NOTE: Diffusers upgrade requires Dynamo export support -flux = [ - "diffusers @ git+https://github.com/huggingface/diffusers.git@7298bdd8177c16eadb74f6166327f5984fd8c69d", - "onnxscript==0.6.2", - "torchao==0.13.0", - "flux @ git+https://github.com/black-forest-labs/flux.git", -] - -# Cosmos family (NVIDIA) -# Pipelines: Cosmos-Predict2 Text2Image (2B, 14B), Cosmos-Predict2 Video2World (2B, 14B), Wan2.2 -cosmos = [ - "diffusers==0.37.1", - "imageio-ffmpeg", - "onnxscript==0.6.2", - "flux @ git+https://github.com/black-forest-labs/flux.git", -] - -# Install all families -all = [ - "tensorrt-diffusion[sd]", - "tensorrt-diffusion[flux]", - "tensorrt-diffusion[cosmos]", -] - -# Development dependencies -dev = [ - "pytest", - "pytest-cov", - "black", - "ruff", -] - - -[build-system] -requires = ["poetry-core>=1.3.0"] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -# Tell Poetry where the actual Python package is located -packages = [{include = "demo_diffusion"}] - -[tool.uv] -# Use PyPI as the main index -index-url = "https://pypi.org/simple" - -# Add NVIDIA's PyPI index for nvidia-modelopt and related packages -[[tool.uv.index]] -name = "nvidia" -url = "https://pypi.nvidia.com" -explicit = true - -[tool.uv.sources] -# Explicitly fetch these packages from NVIDIA's index -nvidia-modelopt = { index = "nvidia" } -onnx-graphsurgeon = { index = "nvidia" } -polygraphy = { index = "nvidia" } - -[tool.ruff] -line-length = 120 -target-version = "py310" - -[tool.ruff.lint] -select = ["E", "F", "W", "I"] -ignore = ["E501"] # Line too long (handled by formatter) - -[tool.pytest.ini_options] -testpaths = ["tests"] -python_files = ["test_*.py"] -python_functions = ["test_*"] - -[tool.black] -line-length = 120 -target-version = ["py310", "py311", "py312"] diff --git a/demo/Diffusion/requirements.txt b/demo/Diffusion/requirements.txt deleted file mode 100755 index 8947b7ada..000000000 --- a/demo/Diffusion/requirements.txt +++ /dev/null @@ -1,24 +0,0 @@ -apex==0.9.10dev -accelerate==1.2.1 -colored -controlnet_aux==0.0.6 -cuda-python -diffusers==0.35.2 -git+https://github.com/black-forest-labs/flux.git -ftfy -matplotlib -nvtx -onnx==1.18.0 -onnxscript==0.5.4 -opencv-python-headless==4.8.0.74 -scipy -transformers==4.52.4 ---extra-index-url https://pypi.nvidia.com -nvidia-modelopt[torch,onnx]==0.31.0 -onnx-graphsurgeon==0.5.2 -peft==0.17.0 -polygraphy==0.49.22 -sentencepiece -numpy==1.26.4 -imageio-ffmpeg - diff --git a/demo/Diffusion/setup.py b/demo/Diffusion/setup.py deleted file mode 100644 index b43395401..000000000 --- a/demo/Diffusion/setup.py +++ /dev/null @@ -1,578 +0,0 @@ -#!/usr/bin/env python3 -# -# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -""" -Setup script for TensorRT Diffusion dependencies. - -Usage: - python setup.py [GROUP] [OPTIONS] - -Groups: - sd = SD 1.4, SDXL, SD3, SD3.5, SVD, Stable Cascade (Stability AI) - flux = Flux models (Black Forest Labs) - cosmos = Cosmos models (NVIDIA), Wan2.2 T2V - all = Install all groups (default) - -Options: - --skip-tensorrt Skip TensorRT upgrade/installation - --force Force reinstallation even if already installed - --deps-root DIR Root directory for dependencies - -q, --quiet Suppress informational output (errors are always shown) - -Examples: - python setup.py # Install all - python setup.py sd # Install SD family only - python setup.py flux # Install Flux only - python setup.py cosmos # Install Cosmos only - python setup.py --skip-tensorrt # Install all, skip TensorRT upgrade - python setup.py flux --skip-tensorrt # Install Flux only, skip TensorRT upgrade - python setup.py all --quiet # Install all, minimal output -""" - -import argparse -import os -import re -import shutil -import subprocess -import sys -import tempfile -from pathlib import Path -# Global quiet flag (set by parse_args) -_quiet = False - - -def log(msg: str = ""): - """Print a message unless in quiet mode.""" - if not _quiet: - print(msg) - -# Group descriptions -GROUP_DESCRIPTIONS = { - "sd": "SD family (SD 1.4, SDXL, SD3, SD3.5, SVD, Stable Cascade)", - "flux": "Flux family (Black Forest Labs)", - "cosmos": "Cosmos family (NVIDIA), Wan2.2 T2V", -} - -# Valid dependency groups -VALID_GROUPS = set(GROUP_DESCRIPTIONS.keys()) - -# Default installation root -# Can be overridden by: -# 1. Environment variable: TENSORRT_DIFFUSION_DEPS_ROOT -# 2. Command-line argument: --deps-root -DEFAULT_DEPS_ROOT = os.environ.get("TENSORRT_DIFFUSION_DEPS_ROOT", "/workspace/deps") - -# Marker file to indicate successful installation -# This file is created after all packages are successfully installed -# Prevents treating incomplete installations as complete -INSTALL_COMPLETE_MARKER = ".install_complete" - - -def _normalize_package_name(name: str) -> str: - """Normalize a package name per PEP 503 (e.g. 'Nvidia_ModelOpt' -> 'nvidia-modelopt').""" - return re.sub(r"[-_.]+", "-", name).lower() - - -# Regex to extract the package name from a PEP 508 requirement string. -# Matches the leading identifier before any extras, version specifier, or URL marker. -# "nvidia-modelopt[torch,onnx]==0.40.0" -> "nvidia-modelopt" -# "flux @ git+https://..." -> "flux" -_REQ_NAME_RE = re.compile(r"^([A-Za-z0-9]([A-Za-z0-9._-]*[A-Za-z0-9])?)") - - -def get_pyproject_package_names(pyproject_path: str, group: str) -> set[str]: - """Return normalized names of packages explicitly listed in pyproject.toml.""" - try: - import tomllib - except ModuleNotFoundError: - try: - import tomli as tomllib - except ModuleNotFoundError: - return set() - - with open(pyproject_path, "rb") as f: - data = tomllib.load(f) - - project = data.get("project", {}) - reqs = list(project.get("dependencies", [])) - reqs.extend(project.get("optional-dependencies", {}).get(group, [])) - - names = set() - for req in reqs: - match = _REQ_NAME_RE.match(req.strip()) - if match: - names.add(_normalize_package_name(match.group(1))) - return names - - -def get_container_provided_packages() -> list[str]: - """Discover torch/NVIDIA packages already installed in the container.""" - from importlib.metadata import distributions - prefixes = ("torch", "torchvision", "triton", "nvidia-") - return sorted({ - dist.metadata["Name"].lower() - for dist in distributions() - if dist.metadata["Name"].lower().startswith(prefixes) - }) - - -def print_header(): - """Print setup header.""" - log("=" * 60) - log(" TensorRT Diffusion - Dependency Setup") - log("=" * 60) - - -def check_uv_installed() -> tuple[bool, bool]: - """ - Check if uv is installed and accessible. - - Returns: - tuple: (is_installed, needs_path_setup) - - is_installed: True if uv is available - - needs_path_setup: True if user needs to add ~/.local/bin to PATH permanently - """ - # First check if uv is in PATH - try: - subprocess.run( - ["uv", "--version"], - capture_output=True, - check=True, - text=True - ) - return True, False - except (subprocess.CalledProcessError, FileNotFoundError): - # If not in PATH, check the default installation location - local_bin = os.path.expanduser("~/.local/bin") - uv_path = os.path.join(local_bin, "uv") - - if os.path.exists(uv_path) and os.access(uv_path, os.X_OK): - # uv exists but not in PATH - add it temporarily for this script - if local_bin not in os.environ["PATH"]: - os.environ["PATH"] = f"{local_bin}:{os.environ['PATH']}" - return True, True # Needs permanent PATH setup - - return False, False - - -def upgrade_tensorrt(pip_spec: str) -> bool: - """Upgrade/install TensorRT using pip. - - Args: - pip_spec: PIP specifier for TensorRT, e.g. "tensorrt-cu13" or "tensorrt-cu13==10.16.*" - - Returns: - True on success, False otherwise - """ - print("Installing TensorRT: {}".format(pip_spec)) - try: - subprocess.run( - [sys.executable, "-m", "pip", "install", "--upgrade", "--pre", pip_spec], - check=True, - capture_output=_quiet, - ) - # Print installed version for confirmation - try: - import importlib - trt = importlib.import_module("tensorrt") - log(f" Installed TensorRT version: {getattr(trt, '__version__', 'unknown')}") - except Exception: - pass - return True - except subprocess.CalledProcessError as e: - print(f"Failed to upgrade/install TensorRT: {e}") - return False - - -def install_libgl1() -> bool: - """Install libgl1 system package when possible (Debian/Ubuntu). - - Returns: - True if successfully installed or already present, False otherwise. - """ - print("Checking for libgl1 (system dependency)...") - apt_get = shutil.which("apt-get") - if not apt_get: - log(" Skipping: apt-get not found. Please install 'libgl1' via your OS package manager.") - return False - - sudo = shutil.which("sudo") - use_sudo = False - try: - use_sudo = (hasattr(os, "geteuid") and os.geteuid() != 0 and sudo is not None) - except Exception: - use_sudo = sudo is not None - - try: - # Update package list first - cmd_update = ([sudo] if use_sudo else []) + [apt_get, "update"] - subprocess.run(cmd_update, check=True, capture_output=_quiet) - - cmd_install = ([sudo] if use_sudo else []) + [apt_get, "install", "-y", "libgl1"] - subprocess.run(cmd_install, check=True, capture_output=_quiet) - log(" libgl1 installed (or already up to date)") - return True - except subprocess.CalledProcessError as e: - print(f" Warning: Failed to install libgl1: {e}") - print(" Please install 'libgl1' manually via your OS package manager.") - return False - - -def install_uv(): - """Install uv package manager.""" - log("Installing uv...") - try: - # Download and run uv installer - curl_cmd = [ - "curl", "-LsSf", - "https://astral.sh/uv/install.sh" - ] - - curl_process = subprocess.Popen( - curl_cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - - sh_process = subprocess.Popen( - ["sh"], - stdin=curl_process.stdout, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) - - curl_process.stdout.close() - stdout, stderr = sh_process.communicate() - - if sh_process.returncode != 0: - print(f"Failed to install uv: {stderr.decode()}") - sys.exit(1) - - # Add to PATH for this session - # uv installer uses ~/.local/bin by default - local_bin = os.path.expanduser("~/.local/bin") - if local_bin not in os.environ["PATH"]: - os.environ["PATH"] = f"{local_bin}:{os.environ['PATH']}" - log("uv installed successfully") - - except Exception as e: - print(f"Error installing uv: {e}") - print("Please install manually: curl -LsSf https://astral.sh/uv/install.sh | sh") - sys.exit(1) - - -def get_installed_groups(deps_root: str) -> set[str]: - """ - Get set of already installed dependency groups. - - A group is considered installed only if both: - 1. The group directory exists - 2. The .install_complete marker file exists in that directory - - Args: - deps_root: Root directory where dependencies are installed - - Returns: - Set of installed group names - """ - installed = set() - deps_path = Path(deps_root) - - if not deps_path.exists(): - return installed - - for group in VALID_GROUPS: - group_dir = deps_path / group - marker_file = group_dir / INSTALL_COMPLETE_MARKER - - # Only consider it installed if marker file exists - if group_dir.exists() and marker_file.exists(): - installed.add(group) - - return installed - - -def install_group(group: str, deps_root: str, project_root: str) -> bool: - """ - Install dependencies for a specific group. - - Args: - group: Dependency group name - deps_root: Root directory where dependencies will be installed - project_root: Project root directory (where pyproject.toml is) - - Returns: - True if installation succeeded, False otherwise - """ - description = GROUP_DESCRIPTIONS.get(group, group) - install_path = os.path.join(deps_root, group) - - print(f"Installing {description}...") - log(f" Location: {install_path}") - - try: - # Determine Python version and site-packages path - python_version = f"{sys.version_info.major}.{sys.version_info.minor}" - site_packages = Path(install_path) / "lib" / f"python{python_version}" / "site-packages" - - # Create site-packages directory if it doesn't exist - site_packages.mkdir(parents=True, exist_ok=True) - - # Build an overrides file so uv never installs packages that are - # already installed in the container. Exclude packages explicitly - # listed in pyproject.toml so they get installed at the pinned version. - container_pkgs = get_container_provided_packages() - declared_pkgs = get_pyproject_package_names( - str(Path(project_root) / "pyproject.toml"), group - ) - overrides_content = "\n".join( - f'{pkg} ; python_version < "0"' - for pkg in container_pkgs - if _normalize_package_name(pkg) not in declared_pkgs - ) - - with tempfile.NamedTemporaryFile( - mode="w", suffix=".txt", prefix="uv_overrides_", delete=False - ) as f: - f.write(overrides_content) - overrides_path = f.name - - try: - cmd = [ - "uv", "pip", "install", - "--python-preference", "only-system", - "--prefix", install_path, - "--overrides", overrides_path, - f".[{group}]" - ] - - subprocess.run( - cmd, - cwd=project_root, - text=True, - capture_output=_quiet, - check=True - ) - finally: - os.unlink(overrides_path) - - # Create marker file to indicate successful installation - marker_file = Path(install_path) / INSTALL_COMPLETE_MARKER - marker_file.write_text("Installation completed successfully\n") - - print(f" {description} installed successfully") - return True - - except subprocess.CalledProcessError as e: - print(f"Failed to install {description}") - print(f" Error: {e}") - - # Clean up incomplete installation - if os.path.exists(install_path): - log(f" Cleaning up incomplete installation at {install_path}") - try: - shutil.rmtree(install_path) - except Exception as cleanup_error: - print(f" Warning: Failed to clean up: {cleanup_error}") - - return False - - -def determine_groups_to_install(requested: str, already_installed: set[str]) -> list[str]: - """ - Determine which groups need to be installed. - - Args: - requested: Requested group or "all" - already_installed: Set of already installed groups - - Returns: - List of groups to install - """ - if requested == "all": - return sorted(VALID_GROUPS - already_installed) - elif requested in VALID_GROUPS: - return [] if requested in already_installed else [requested] - return [] - - -def print_summary(installed_groups: set[str]): - """ - Print summary of installed groups. - - Args: - installed_groups: Set of all installed groups - """ - log("=" * 60) - print("Setup complete!") - log("=" * 60) - - if installed_groups: - log("Installed groups:") - for group in sorted(installed_groups): - description = GROUP_DESCRIPTIONS.get(group, group) - log(f" {description}") - - log("Each demo script automatically uses the correct dependencies.") - else: - log("No groups installed.") - - log() - - -def parse_args(): - """Parse command line arguments.""" - parser = argparse.ArgumentParser( - description="Setup TensorRT Diffusion dependencies", - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog=""" -Examples: - python setup.py # Install all groups - python setup.py sd # Install SD family only - python setup.py flux # Install Flux only - python setup.py cosmos # Install Cosmos only - -Groups: - sd - SD 1.4, SDXL, SD3, SD3.5, SVD, Stable Cascade (Stability AI) - flux - Flux models (Black Forest Labs) - cosmos - Cosmos models (NVIDIA) - all - All groups (default) - """ - ) - - parser.add_argument( - "group", - nargs="?", - default="all", - choices=list(VALID_GROUPS) + ["all"], - help="Dependency group to install (default: all)" - ) - - parser.add_argument( - "--deps-root", - default=DEFAULT_DEPS_ROOT, - help=f"Root directory for dependencies (default: {DEFAULT_DEPS_ROOT})" - ) - - parser.add_argument( - "--force", - action="store_true", - help="Force reinstallation even if already installed" - ) - - parser.add_argument("--skip-tensorrt", action="store_true", help="Skip TensorRT upgrade/installation") - - parser.add_argument("-q", "--quiet", action="store_true", help="Suppress informational output (errors are always shown)") - - return parser.parse_args() - - -def main(): - """Main setup function.""" - args = parse_args() - - global _quiet - _quiet = args.quiet - - print_header() - - # Check/install uv - uv_installed, needs_path_setup = check_uv_installed() - if not uv_installed: - install_uv() - needs_path_setup = True # Fresh install always needs PATH setup - else: - log("uv is already installed") - if needs_path_setup: - log(" (temporarily added ~/.local/bin to PATH for this session)") - - # Get project root (where pyproject.toml is) - project_root = str(Path(__file__).parent.absolute()) - pyproject_path = Path(project_root) / "pyproject.toml" - - if not pyproject_path.exists(): - print(f"Error: pyproject.toml not found in {project_root}") - print(" Make sure you're running this script from the project root.") - sys.exit(1) - - # Check what's already installed - installed_groups = get_installed_groups(args.deps_root) - - # Install system dependency (best-effort) and ensure TensorRT is present - install_libgl1() - if not args.skip_tensorrt: - upgrade_tensorrt("tensorrt-cu13") - else: - log("Skipping TensorRT upgrade (--skip-tensorrt specified)") - - if installed_groups and not args.force: - log(f"Already installed: {', '.join(sorted(installed_groups))}") - - # Determine what to install - if args.force and args.group == "all": - groups_to_install = sorted(VALID_GROUPS) - elif args.force and args.group in VALID_GROUPS: - groups_to_install = [args.group] - else: - groups_to_install = determine_groups_to_install(args.group, installed_groups) - - # Early exit if nothing to do - if not groups_to_install: - if args.group == "all": - print("All requested dependencies are already installed!") - else: - description = GROUP_DESCRIPTIONS.get(args.group, args.group) - print(f"{description} is already installed!") - log(f" To reinstall, use --force flag or remove {args.deps_root}/{args.group}") - print_summary(installed_groups) - sys.exit(0) - - # Install groups - print(f"Installing {len(groups_to_install)} group(s): {', '.join(groups_to_install)}") - - success_count = 0 - for group in groups_to_install: - if install_group(group, args.deps_root, project_root): - installed_groups.add(group) - success_count += 1 - - # Print summary - print_summary(installed_groups) - - # Print PATH setup instructions if needed - if needs_path_setup: - print() - print("=" * 60) - print(" Action Required: Update PATH") - print("=" * 60) - print("uv was installed to ~/.local/bin but is not in your PATH.") - print() - print("To make uv available in future sessions, run:") - print(" source ~/.local/bin/env") - print() - print("Or restart your shell.") - print("=" * 60) - - # Exit with error if any installations failed - if success_count < len(groups_to_install): - print(f"Warning: {len(groups_to_install) - success_count} group(s) failed to install") - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/demo/Diffusion/setup.sh b/demo/Diffusion/setup.sh deleted file mode 100644 index 8da259e96..000000000 --- a/demo/Diffusion/setup.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Minimal and backward-compatible: default to modern requirements, allow override via env. -REQ_FILE="${REQUIREMENTS_FILE:-requirements.txt}" -echo "[I] Using requirements file: ${REQ_FILE} (override with REQUIREMENTS_FILE=)" - -# Upgrade pip and install TensorRT -python3 -m pip install --upgrade pip -pip3 install --pre tensorrt-cu12 - -# Install the required packages -PIP_CONSTRAINT= pip3 install -r "${REQ_FILE}" - -# Install libgl1 -# Check if apt-get is available -if command -v apt-get >/dev/null 2>&1; then - sudo apt-get install -y libgl1 -else - echo "Warning: apt-get not found. Please install libgl1 manually for your system." -fi - diff --git a/demo/Diffusion/tests/poetry.lock b/demo/Diffusion/tests/poetry.lock deleted file mode 100644 index a3a4f3215..000000000 --- a/demo/Diffusion/tests/poetry.lock +++ /dev/null @@ -1,183 +0,0 @@ -# This file is automatically @generated by Poetry 2.1.0 and should not be changed by hand. - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["main"] -markers = "sys_platform == \"win32\"" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.3.0" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -groups = ["main"] -markers = "python_version < \"3.11\"" -files = [ - {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, - {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, -] - -[package.dependencies] -typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "iniconfig" -version = "2.1.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, - {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, -] - -[[package]] -name = "packaging" -version = "25.0" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, -] - -[[package]] -name = "pluggy" -version = "1.6.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, - {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["coverage", "pytest", "pytest-benchmark"] - -[[package]] -name = "pygments" -version = "2.19.2" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, - {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, -] - -[package.extras] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pytest" -version = "8.4.2" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79"}, - {file = "pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01"}, -] - -[package.dependencies] -colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""} -iniconfig = ">=1" -packaging = ">=20" -pluggy = ">=1.5,<2" -pygments = ">=2.7.2" -tomli = {version = ">=1", markers = "python_version < \"3.11\""} - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "tomli" -version = "2.3.0" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -groups = ["main"] -markers = "python_version < \"3.11\"" -files = [ - {file = "tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45"}, - {file = "tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba"}, - {file = "tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf"}, - {file = "tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441"}, - {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845"}, - {file = "tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c"}, - {file = "tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456"}, - {file = "tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be"}, - {file = "tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac"}, - {file = "tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22"}, - {file = "tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f"}, - {file = "tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52"}, - {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8"}, - {file = "tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6"}, - {file = "tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876"}, - {file = "tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878"}, - {file = "tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b"}, - {file = "tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae"}, - {file = "tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b"}, - {file = "tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf"}, - {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f"}, - {file = "tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05"}, - {file = "tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606"}, - {file = "tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999"}, - {file = "tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e"}, - {file = "tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3"}, - {file = "tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc"}, - {file = "tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0"}, - {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879"}, - {file = "tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005"}, - {file = "tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463"}, - {file = "tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8"}, - {file = "tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77"}, - {file = "tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf"}, - {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530"}, - {file = "tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b"}, - {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67"}, - {file = "tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f"}, - {file = "tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0"}, - {file = "tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba"}, - {file = "tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b"}, - {file = "tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549"}, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -description = "Backported and Experimental Type Hints for Python 3.9+" -optional = false -python-versions = ">=3.9" -groups = ["main"] -markers = "python_version < \"3.11\"" -files = [ - {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, - {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, -] - -[metadata] -lock-version = "2.1" -python-versions = ">=3.10,<3.13" -content-hash = "e5b22cd40b06ff329e8271eaf4447542ab0b5a882e45a8db64107ac99f2931d0" diff --git a/demo/Diffusion/tests/pyproject.toml b/demo/Diffusion/tests/pyproject.toml deleted file mode 100644 index 7cf5f8bf5..000000000 --- a/demo/Diffusion/tests/pyproject.toml +++ /dev/null @@ -1,15 +0,0 @@ -[project] -name = "tensorrt-tests" -version = "0.1.0" -description = "" -dependencies = [ "pytest",] -requires-python = ">=3.10,<3.13" -[[project.authors]] -name = "TensorRT" -email = "svc_tensorrt@nvidia.com" - -[build-system] -requires = [ "poetry-core>=1.3.0",] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] diff --git a/demo/Diffusion/tests/requirements.txt b/demo/Diffusion/tests/requirements.txt deleted file mode 100644 index e079f8a60..000000000 --- a/demo/Diffusion/tests/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pytest diff --git a/demo/Diffusion/tests/test_utils_modelopt.py b/demo/Diffusion/tests/test_utils_modelopt.py deleted file mode 100644 index aaf5fb3ac..000000000 --- a/demo/Diffusion/tests/test_utils_modelopt.py +++ /dev/null @@ -1,62 +0,0 @@ -# -# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import numpy as np -import onnx_graphsurgeon as gs - -from demo_diffusion import utils_modelopt - - -def create_graph_with_fp16_resize() -> gs.Graph: - """Return a gs.Graph with a single Resize node with FP16 input.""" - return gs.Graph( - nodes=[ - gs.Node( - op="Resize", - name="my_resize_node", - inputs=[ - gs.Variable(name="X", dtype=np.float16), - gs.Variable(name="roi", dtype=np.float16), - gs.Variable(name="scales", dtype=np.float16), - gs.Variable(name="sizes", dtype=np.int64), - ], - outputs=[gs.Variable(name="Y", dtype=np.float16)], - ) - ] - ) - - -def test_should_cast_resize_to_fp32() -> None: - """Test that `cast_resize_to_fp32` correctly casts all Resize nodes to FP32.""" - # Precondition. - graph = create_graph_with_fp16_resize() - - # Under test. - utils_modelopt.cast_resize_io(graph) - - # Postcondition. - has_resize = False - for node in graph.nodes: - if node.op == "Resize": - has_resize = True - x, roi, scales, sizes = node.inputs - assert x.dtype == np.float32 - assert roi.dtype == np.float32 - assert scales.dtype == np.float32 - assert sizes.dtype == np.int64 # "sizes" is the exception input that cannot be cast to FP32. - - assert has_resize