diff --git a/onnxruntime/python/tools/transformers/models/stable_diffusion/demo_txt2img.py b/onnxruntime/python/tools/transformers/models/stable_diffusion/demo_txt2img.py index 40692701c2..2cd64e8784 100644 --- a/onnxruntime/python/tools/transformers/models/stable_diffusion/demo_txt2img.py +++ b/onnxruntime/python/tools/transformers/models/stable_diffusion/demo_txt2img.py @@ -61,6 +61,7 @@ if __name__ == "__main__": controlnet_scales=controlnet_scale, show_latency=not warmup, output_type="pil", + deterministic=args.deterministic, ) if not args.disable_cuda_graph: diff --git a/onnxruntime/python/tools/transformers/models/stable_diffusion/demo_utils.py b/onnxruntime/python/tools/transformers/models/stable_diffusion/demo_utils.py index 965a2598a2..32c673416f 100644 --- a/onnxruntime/python/tools/transformers/models/stable_diffusion/demo_utils.py +++ b/onnxruntime/python/tools/transformers/models/stable_diffusion/demo_utils.py @@ -239,6 +239,7 @@ def parse_arguments(is_xl: bool, parser): ) parser.add_argument("--nvtx-profile", action="store_true", help="Enable NVTX markers for performance profiling.") parser.add_argument("--seed", type=int, default=None, help="Seed for random generator to get consistent results.") + parser.add_argument("--deterministic", action="store_true", help="use deterministic algorithms.") parser.add_argument("-dc", "--disable-cuda-graph", action="store_true", help="Disable cuda graph.") group = parser.add_argument_group("Options for ORT_CUDA engine only") diff --git a/onnxruntime/python/tools/transformers/models/stable_diffusion/pipeline_stable_diffusion.py b/onnxruntime/python/tools/transformers/models/stable_diffusion/pipeline_stable_diffusion.py index 104ce984bd..0ad8b13b60 100644 --- a/onnxruntime/python/tools/transformers/models/stable_diffusion/pipeline_stable_diffusion.py +++ b/onnxruntime/python/tools/transformers/models/stable_diffusion/pipeline_stable_diffusion.py @@ -754,6 +754,7 @@ class StableDiffusionPipeline: controlnet_scales: Optional[torch.Tensor] = None, show_latency: bool = False, output_type: str = "pil", + deterministic: bool = False, ): """ Run the diffusion pipeline. @@ -783,6 +784,9 @@ class StableDiffusionPipeline: output_type (str): It can be "latent", "pt" or "pil". """ + if deterministic: + torch.use_deterministic_algorithms(True) + if self.is_backend_tensorrt(): import tensorrt as trt from trt_utilities import TRT_LOGGER diff --git a/onnxruntime/python/tools/transformers/models/stable_diffusion/test/astronaut_riding_txt2image-DDIM-50.png b/onnxruntime/python/tools/transformers/models/stable_diffusion/test/astronaut_riding_txt2image-DDIM-50.png new file mode 100644 index 0000000000..9d20ce5503 Binary files /dev/null and b/onnxruntime/python/tools/transformers/models/stable_diffusion/test/astronaut_riding_txt2image-DDIM-50.png differ diff --git a/onnxruntime/python/tools/transformers/models/stable_diffusion/test/check_image.py b/onnxruntime/python/tools/transformers/models/stable_diffusion/test/check_image.py new file mode 100644 index 0000000000..fcfe8b081f --- /dev/null +++ b/onnxruntime/python/tools/transformers/models/stable_diffusion/test/check_image.py @@ -0,0 +1,68 @@ +import argparse +import os + +import cv2 +import open_clip +import torch +from PIL import Image +from sentence_transformers import util + + +def arg_parser(): + parser = argparse.ArgumentParser(description="Options for Compare 2 image") + parser.add_argument("--image1", type=str, help="Path to image 1") + parser.add_argument("--image2", type=str, help="Path to image 2") + args = parser.parse_args() + return args + + +def image_encoder(img: Image.Image): # -> torch.Tensor: + device = "cuda" if torch.cuda.is_available() else "cpu" + model, _, preprocess = open_clip.create_model_and_transforms("ViT-B-16-plus-240", pretrained="laion400m_e32") + model.to(device) + + img1 = Image.fromarray(img).convert("RGB") + img1 = preprocess(img1).unsqueeze(0).to(device) + img1 = model.encode_image(img1) + return img1 + + +def load_image(image_path: str): # -> Image.Image: + # cv2.imread() can silently fail when the path is too long + # https://stackoverflow.com/questions/68716321/how-to-use-absolute-path-in-cv2-imread + if os.path.isabs(image_path): + directory = os.path.dirname(image_path) + current_directory = os.getcwd() + os.chdir(directory) + img = cv2.imread(os.path.basename(image_path), cv2.IMREAD_UNCHANGED) + os.chdir(current_directory) + else: + img = cv2.imread(image_path, cv2.IMREAD_UNCHANGED) + return img + + +def generate_score(image1: str, image2: str): # -> float: + test_img = load_image(image1) + data_img = load_image(image2) + img1 = image_encoder(test_img) + img2 = image_encoder(data_img) + cos_scores = util.pytorch_cos_sim(img1, img2) + score = round(float(cos_scores[0][0]) * 100, 2) + return score + + +def main(): + args = arg_parser() + image1 = args.image1 + image2 = args.image2 + score = round(generate_score(image1, image2), 2) + print("similarity Score: ", {score}) + if score < 99: + print(f"{image1} and {image2} are different") + raise SystemExit(1) + else: + print(f"{image1} and {image2} are same") + + +if __name__ == "__main__": + main() diff --git a/onnxruntime/python/tools/transformers/models/stable_diffusion/test/requirements.txt b/onnxruntime/python/tools/transformers/models/stable_diffusion/test/requirements.txt new file mode 100644 index 0000000000..e51ffb395c --- /dev/null +++ b/onnxruntime/python/tools/transformers/models/stable_diffusion/test/requirements.txt @@ -0,0 +1,4 @@ +git+https://github.com/openai/CLIP.git +open_clip_torch +sentence_transformers +pillow diff --git a/tools/ci_build/github/azure-pipelines/bigmodels-ci-pipeline.yml b/tools/ci_build/github/azure-pipelines/bigmodels-ci-pipeline.yml index b767b7276b..dd88a4d6d5 100644 --- a/tools/ci_build/github/azure-pipelines/bigmodels-ci-pipeline.yml +++ b/tools/ci_build/github/azure-pipelines/bigmodels-ci-pipeline.yml @@ -1,3 +1,32 @@ +##### start trigger Don't edit it manually, Please do edit set-trigger-rules.py #### +trigger: + branches: + include: + - main + - rel-* + paths: + exclude: + - docs/** + - README.md + - CONTRIBUTING.md + - BUILD.md + - 'js/web' + - 'onnxruntime/core/providers/js' +pr: + branches: + include: + - main + - rel-* + paths: + exclude: + - docs/** + - README.md + - CONTRIBUTING.md + - BUILD.md + - 'js/web' + - 'onnxruntime/core/providers/js' +#### end trigger ####parameters: + # reference: https://github.com/microsoft/onnxruntime/blob/main/onnxruntime/python/tools/transformers/models/stable_diffusion/README.md parameters: - name: specificArtifact @@ -143,7 +172,6 @@ stages: - job: Stable_Diffusion variables: skipComponentGovernanceDetection: true - CCACHE_DIR: $(Pipeline.Workspace)/ccache workspace: clean: all pool: onnxruntime-Linux-GPU-A10-12G @@ -162,7 +190,7 @@ stages: - script: | docker run --rm --gpus all -v $PWD:/workspace -v $(Build.BinariesDirectory)/Release:/Release nvcr.io/nvidia/pytorch:22.11-py3 \ - bash -c " + bash -c ' set -ex; \ python3 --version; \ python3 -m pip install --upgrade pip; \ @@ -171,12 +199,31 @@ stages: python3 -m pip install -r requirements-cuda11.txt; \ python3 -m pip install --upgrade polygraphy onnx-graphsurgeon --extra-index-url https://pypi.ngc.nvidia.com; \ echo Generate an image guided by a text prompt; \ - python3 demo_txt2img.py 'astronaut riding a horse on mars'; \ - popd; \ - " + python3 demo_txt2img.py --seed 1 --deterministic "astronaut riding a horse on mars" ; \ + find $(pwd) -name "*.png" ; \ + popd ; \ + ' displayName: 'Run stable diffusion demo' workingDirectory: $(Build.SourcesDirectory) + - script: | + docker run --rm --gpus all -v $PWD:/workspace nvcr.io/nvidia/pytorch:22.11-py3 \ + bash -c ' + set -ex; \ + python3 --version; \ + python3 -m pip install --upgrade pip; \ + pushd /workspace/onnxruntime/python/tools/transformers/models/stable_diffusion/; \ + image2=$(find $(pwd) -name "astronaut_riding_a_h*.png") ; \ + pushd test; \ + python3 -m pip install -r requirements.txt; \ + echo check demo_txt2image.py generate image; \ + python3 -u check_image.py --image1 astronaut_riding_txt2image-DDIM-50.png --image2 $image2; \ + popd ; \ + popd ; \ + ' + displayName: 'Check the generated image' + workingDirectory: $(Build.SourcesDirectory) + - stage: Llama2_ONNX_FP16 dependsOn: - Build_Onnxruntime_Cuda diff --git a/tools/ci_build/set-trigger-rules.py b/tools/ci_build/set-trigger-rules.py index cdb75154ec..d26fec4103 100644 --- a/tools/ci_build/set-trigger-rules.py +++ b/tools/ci_build/set-trigger-rules.py @@ -14,6 +14,7 @@ skip_doc_changes = ["web-ci-pipeline.yml"] skip_js_changes = [ "android-arm64-v8a-QNN-crosscompile-ci-pipeline.yml", "android-x86_64-crosscompile-ci-pipeline.yml", + "bigmodels-ci-pipeline.yml", "linux-ci-pipeline.yml", "linux-cpu-aten-pipeline.yml", "linux-cpu-eager-pipeline.yml", @@ -31,7 +32,6 @@ skip_js_changes = [ "orttraining-linux-ci-pipeline.yml", "orttraining-linux-gpu-ci-pipeline.yml", "orttraining-linux-gpu-ortmodule-distributed-test-ci-pipeline.yml", - "orttraining-linux-gpu-training-apis.yml", "orttraining-mac-ci-pipeline.yml", "win-ci-pipeline.yml", "win-gpu-ci-pipeline.yml",