├── image-1.jpeg ├── image-2.jpeg ├── image-3.jpeg ├── environment.yml ├── README.md ├── .gitignore ├── LICENSE └── inpaint.ipynb /image-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machinelearnear/openai-glide-text2im/main/image-1.jpeg -------------------------------------------------------------------------------- /image-2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machinelearnear/openai-glide-text2im/main/image-2.jpeg -------------------------------------------------------------------------------- /image-3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machinelearnear/openai-glide-text2im/main/image-3.jpeg -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | # To use: 2 | # $ conda env create -f environment.yml 3 | # $ conda activate demo 4 | name: machinelearnear-glide-text2im 5 | dependencies: 6 | - python=3.7 7 | - pip 8 | - nb_conda_kernels 9 | - ipykernel 10 | - ipywidgets 11 | - gh 12 | - pip: 13 | - git+https://github.com/openai/glide-text2im 14 | - numpy 15 | - PyYAML 16 | # - -r file:requirements.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GLIDE 2 | 3 | This is sample repo reproducing the official codebase for running the small, filtered-data GLIDE model from [GLIDE: Towards Photorealistic Image Generation and Editing with Text-Guided Diffusion Models](https://arxiv.org/abs/2112.10741). 4 | 5 | For more information, please see the original repo here: https://github.com/openai/glide-text2im/. 6 | 7 | ![Figure-1](image-1.jpeg) 8 | ![Figure-2](image-2.jpeg) 9 | ![Figure-3](image-3.jpeg) 10 | 11 | ## Watch YouTube Explainer Video 12 | [![GLIDE: Generá y editá imágenes en segundos en base a lo que escribis (+ Repo)](https://img.youtube.com/vi/WG20CnktPbk/0.jpg)](https://www.youtube.com/watch?v=WG20CnktPbk) 13 | 14 | ## How to run 15 | 16 | * The [text2im](notebooks/text2im.ipynb) [![Open In Studio Lab](https://studiolab.sagemaker.aws/studiolab.svg)](https://studiolab.sagemaker.aws/import/github/machinelearnear/openai-glide-text2im/blob/main/text2im.ipynb) notebook shows how to use GLIDE (filtered) with classifier-free guidance to produce images conditioned on text prompts. 17 | 18 | * The [inpaint](notebooks/inpaint.ipynb) [![Open In Studio Lab](https://studiolab.sagemaker.aws/studiolab.svg)](https://studiolab.sagemaker.aws/import/github/machinelearnear/openai-glide-text2im/blob/main/inpaint.ipynb) notebook shows how to use GLIDE (filtered) to fill in a masked region of an image, conditioned on a text prompt. 19 | 20 | * The [clip_guided](notebooks/clip_guided.ipynb) [![Open In Studio Lab](https://studiolab.sagemaker.aws/studiolab.svg)](https://studiolab.sagemaker.aws/import/github/machinelearnear/openai-glide-text2im/blob/main/clip-guided.ipynb) notebook shows how to use GLIDE (filtered) + a filtered noise-aware CLIP model to produce images conditioned on text prompts. 21 | 22 | ## References 23 | ``` 24 | @misc{nichol2021glide, 25 | title={GLIDE: Towards Photorealistic Image Generation and Editing with Text-Guided Diffusion Models}, 26 | author={Alex Nichol and Prafulla Dhariwal and Aditya Ramesh and Pranav Shyam and Pamela Mishkin and Bob McGrew and Ilya Sutskever and Mark Chen}, 27 | year={2021}, 28 | eprint={2112.10741}, 29 | archivePrefix={arXiv}, 30 | primaryClass={cs.CV} 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /inpaint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "[![Open In Studio Lab](https://studiolab.sagemaker.aws/studiolab.svg)](https://studiolab.sagemaker.aws/import/github/machinelearnear/openai-glide-text2im/blob/main/inpaint.ipynb)" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "# GLIDE: Towards Photorealistic Image Generation and Editing with Text-Guided Diffusion Models\n", 15 | "- https://arxiv.org/abs/2112.10741" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "## Install dependencies & setup notebook" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": null, 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "# Run this line in Colab to install the package if it is\n", 32 | "# not already installed.\n", 33 | "# !pip install git+https://github.com/openai/glide-text2im" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 2, 39 | "metadata": {}, 40 | "outputs": [], 41 | "source": [ 42 | "from typing import Tuple\n", 43 | "\n", 44 | "from IPython.display import display\n", 45 | "from PIL import Image\n", 46 | "import numpy as np\n", 47 | "import torch as th\n", 48 | "import torch.nn.functional as F\n", 49 | "\n", 50 | "from glide_text2im.download import load_checkpoint\n", 51 | "from glide_text2im.model_creation import (\n", 52 | " create_model_and_diffusion,\n", 53 | " model_and_diffusion_defaults,\n", 54 | " model_and_diffusion_defaults_upsampler\n", 55 | ")" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 3, 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "# This notebook supports both CPU and GPU.\n", 65 | "# On CPU, generating one sample may take on the order of 20 minutes.\n", 66 | "# On a GPU, it should be under a minute.\n", 67 | "\n", 68 | "has_cuda = th.cuda.is_available()\n", 69 | "device = th.device('cpu' if not has_cuda else 'cuda')" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 4, 75 | "metadata": {}, 76 | "outputs": [ 77 | { 78 | "data": { 79 | "application/vnd.jupyter.widget-view+json": { 80 | "model_id": "83f22a4d88e7456cb800b2a62c37571b", 81 | "version_major": 2, 82 | "version_minor": 0 83 | }, 84 | "text/plain": [ 85 | " 0%| | 0.00/1.54G [00:00 Tuple[th.Tensor, th.Tensor]:\n", 169 | " pil_img = Image.open(path).convert('RGB')\n", 170 | " pil_img = pil_img.resize((size, size), resample=Image.BICUBIC)\n", 171 | " img = np.array(pil_img)\n", 172 | " return th.from_numpy(img)[None].permute(0, 3, 1, 2).float() / 127.5 - 1" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "## Sampling parameters" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 7, 185 | "metadata": {}, 186 | "outputs": [ 187 | { 188 | "data": { 189 | "image/png": "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\n", 190 | "text/plain": [ 191 | "" 192 | ] 193 | }, 194 | "metadata": {}, 195 | "output_type": "display_data" 196 | } 197 | ], 198 | "source": [ 199 | "# Sampling parameters\n", 200 | "prompt = \"a corgi in a field\"\n", 201 | "batch_size = 1\n", 202 | "guidance_scale = 5.0\n", 203 | "\n", 204 | "# Tune this parameter to control the sharpness of 256x256 images.\n", 205 | "# A value of 1.0 is sharper, but sometimes results in grainy artifacts.\n", 206 | "upsample_temp = 0.997\n", 207 | "\n", 208 | "# Source image we are inpainting\n", 209 | "source_image_256 = read_image('grass.png', size=256)\n", 210 | "source_image_64 = read_image('grass.png', size=64)\n", 211 | "\n", 212 | "# The mask should always be a boolean 64x64 mask, and then we\n", 213 | "# can upsample it for the second stage.\n", 214 | "source_mask_64 = th.ones_like(source_image_64)[:, :1]\n", 215 | "source_mask_64[:, :, 20:] = 0\n", 216 | "source_mask_256 = F.interpolate(source_mask_64, (256, 256), mode='nearest')\n", 217 | "\n", 218 | "# Visualize the image we are inpainting\n", 219 | "show_images(source_image_256 * source_mask_256)" 220 | ] 221 | }, 222 | { 223 | "cell_type": "markdown", 224 | "metadata": {}, 225 | "source": [ 226 | "## Sample from the base model" 227 | ] 228 | }, 229 | { 230 | "cell_type": "code", 231 | "execution_count": 8, 232 | "metadata": {}, 233 | "outputs": [ 234 | { 235 | "data": { 236 | "application/vnd.jupyter.widget-view+json": { 237 | "model_id": "a9f058a7883048d6982f52a5c95ee3dc", 238 | "version_major": 2, 239 | "version_minor": 0 240 | }, 241 | "text/plain": [ 242 | " 0%| | 0/100 [00:00" 253 | ] 254 | }, 255 | "metadata": {}, 256 | "output_type": "display_data" 257 | } 258 | ], 259 | "source": [ 260 | "# Create the text tokens to feed to the model.\n", 261 | "tokens = model.tokenizer.encode(prompt)\n", 262 | "tokens, mask = model.tokenizer.padded_tokens_and_mask(\n", 263 | " tokens, options['text_ctx']\n", 264 | ")\n", 265 | "\n", 266 | "# Create the classifier-free guidance tokens (empty)\n", 267 | "full_batch_size = batch_size * 2\n", 268 | "uncond_tokens, uncond_mask = model.tokenizer.padded_tokens_and_mask(\n", 269 | " [], options['text_ctx']\n", 270 | ")\n", 271 | "\n", 272 | "# Pack the tokens together into model kwargs.\n", 273 | "model_kwargs = dict(\n", 274 | " tokens=th.tensor(\n", 275 | " [tokens] * batch_size + [uncond_tokens] * batch_size, device=device\n", 276 | " ),\n", 277 | " mask=th.tensor(\n", 278 | " [mask] * batch_size + [uncond_mask] * batch_size,\n", 279 | " dtype=th.bool,\n", 280 | " device=device,\n", 281 | " ),\n", 282 | "\n", 283 | " # Masked inpainting image\n", 284 | " inpaint_image=(source_image_64 * source_mask_64).repeat(full_batch_size, 1, 1, 1).to(device),\n", 285 | " inpaint_mask=source_mask_64.repeat(full_batch_size, 1, 1, 1).to(device),\n", 286 | ")\n", 287 | "\n", 288 | "# Create an classifier-free guidance sampling function\n", 289 | "def model_fn(x_t, ts, **kwargs):\n", 290 | " half = x_t[: len(x_t) // 2]\n", 291 | " combined = th.cat([half, half], dim=0)\n", 292 | " model_out = model(combined, ts, **kwargs)\n", 293 | " eps, rest = model_out[:, :3], model_out[:, 3:]\n", 294 | " cond_eps, uncond_eps = th.split(eps, len(eps) // 2, dim=0)\n", 295 | " half_eps = uncond_eps + guidance_scale * (cond_eps - uncond_eps)\n", 296 | " eps = th.cat([half_eps, half_eps], dim=0)\n", 297 | " return th.cat([eps, rest], dim=1)\n", 298 | "\n", 299 | "def denoised_fn(x_start):\n", 300 | " # Force the model to have the exact right x_start predictions\n", 301 | " # for the part of the image which is known.\n", 302 | " return (\n", 303 | " x_start * (1 - model_kwargs['inpaint_mask'])\n", 304 | " + model_kwargs['inpaint_image'] * model_kwargs['inpaint_mask']\n", 305 | " )\n", 306 | "\n", 307 | "# Sample from the base model.\n", 308 | "model.del_cache()\n", 309 | "samples = diffusion.p_sample_loop(\n", 310 | " model_fn,\n", 311 | " (full_batch_size, 3, options[\"image_size\"], options[\"image_size\"]),\n", 312 | " device=device,\n", 313 | " clip_denoised=True,\n", 314 | " progress=True,\n", 315 | " model_kwargs=model_kwargs,\n", 316 | " cond_fn=None,\n", 317 | " denoised_fn=denoised_fn,\n", 318 | ")[:batch_size]\n", 319 | "model.del_cache()\n", 320 | "\n", 321 | "# Show the output\n", 322 | "show_images(samples)" 323 | ] 324 | }, 325 | { 326 | "cell_type": "markdown", 327 | "metadata": {}, 328 | "source": [ 329 | "## Upsample the 64x64 samples" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": 9, 335 | "metadata": {}, 336 | "outputs": [ 337 | { 338 | "data": { 339 | "application/vnd.jupyter.widget-view+json": { 340 | "model_id": "2b276c29d8054f41a2e2a6913c50cb35", 341 | "version_major": 2, 342 | "version_minor": 0 343 | }, 344 | "text/plain": [ 345 | " 0%| | 0/27 [00:00" 356 | ] 357 | }, 358 | "metadata": {}, 359 | "output_type": "display_data" 360 | } 361 | ], 362 | "source": [ 363 | "tokens = model_up.tokenizer.encode(prompt)\n", 364 | "tokens, mask = model_up.tokenizer.padded_tokens_and_mask(\n", 365 | " tokens, options_up['text_ctx']\n", 366 | ")\n", 367 | "\n", 368 | "# Create the model conditioning dict.\n", 369 | "model_kwargs = dict(\n", 370 | " # Low-res image to upsample.\n", 371 | " low_res=((samples+1)*127.5).round()/127.5 - 1,\n", 372 | "\n", 373 | " # Text tokens\n", 374 | " tokens=th.tensor(\n", 375 | " [tokens] * batch_size, device=device\n", 376 | " ),\n", 377 | " mask=th.tensor(\n", 378 | " [mask] * batch_size,\n", 379 | " dtype=th.bool,\n", 380 | " device=device,\n", 381 | " ),\n", 382 | "\n", 383 | " # Masked inpainting image.\n", 384 | " inpaint_image=(source_image_256 * source_mask_256).repeat(batch_size, 1, 1, 1).to(device),\n", 385 | " inpaint_mask=source_mask_256.repeat(batch_size, 1, 1, 1).to(device),\n", 386 | ")\n", 387 | "\n", 388 | "def denoised_fn(x_start):\n", 389 | " # Force the model to have the exact right x_start predictions\n", 390 | " # for the part of the image which is known.\n", 391 | " return (\n", 392 | " x_start * (1 - model_kwargs['inpaint_mask'])\n", 393 | " + model_kwargs['inpaint_image'] * model_kwargs['inpaint_mask']\n", 394 | " )\n", 395 | "\n", 396 | "# Sample from the base model.\n", 397 | "model_up.del_cache()\n", 398 | "up_shape = (batch_size, 3, options_up[\"image_size\"], options_up[\"image_size\"])\n", 399 | "up_samples = diffusion_up.p_sample_loop(\n", 400 | " model_up,\n", 401 | " up_shape,\n", 402 | " noise=th.randn(up_shape, device=device) * upsample_temp,\n", 403 | " device=device,\n", 404 | " clip_denoised=True,\n", 405 | " progress=True,\n", 406 | " model_kwargs=model_kwargs,\n", 407 | " cond_fn=None,\n", 408 | " denoised_fn=denoised_fn,\n", 409 | ")[:batch_size]\n", 410 | "model_up.del_cache()\n", 411 | "\n", 412 | "# Show the output\n", 413 | "show_images(up_samples)" 414 | ] 415 | }, 416 | { 417 | "cell_type": "code", 418 | "execution_count": null, 419 | "metadata": {}, 420 | "outputs": [], 421 | "source": [ 422 | "from glide_text2im.clip.model_creation import create_clip_model" 423 | ] 424 | }, 425 | { 426 | "cell_type": "code", 427 | "execution_count": null, 428 | "metadata": {}, 429 | "outputs": [], 430 | "source": [ 431 | "## Create CLIP model\n", 432 | "clip_model = create_clip_model(device=device)\n", 433 | "clip_model.image_encoder.load_state_dict(load_checkpoint('clip/image-enc', device))\n", 434 | "clip_model.text_encoder.load_state_dict(load_checkpoint('clip/text-enc', device))" 435 | ] 436 | }, 437 | { 438 | "cell_type": "code", 439 | "execution_count": null, 440 | "metadata": {}, 441 | "outputs": [], 442 | "source": [ 443 | "##############################\n", 444 | "# Sample from the base model #\n", 445 | "##############################\n", 446 | "\n", 447 | "# Create the text tokens to feed to the model.\n", 448 | "tokens = model.tokenizer.encode(prompt)\n", 449 | "tokens, mask = model.tokenizer.padded_tokens_and_mask(\n", 450 | " tokens, options['text_ctx']\n", 451 | ")\n", 452 | "\n", 453 | "# Pack the tokens together into model kwargs.\n", 454 | "model_kwargs = dict(\n", 455 | " tokens=th.tensor([tokens] * batch_size, device=device),\n", 456 | " mask=th.tensor([mask] * batch_size, dtype=th.bool, device=device),\n", 457 | ")\n", 458 | "\n", 459 | "# Setup guidance function for CLIP model.\n", 460 | "cond_fn = clip_model.cond_fn([prompt] * batch_size, guidance_scale)\n", 461 | "\n", 462 | "# Sample from the base model.\n", 463 | "model.del_cache()\n", 464 | "samples = diffusion.p_sample_loop(\n", 465 | " model,\n", 466 | " (batch_size, 3, options[\"image_size\"], options[\"image_size\"]),\n", 467 | " device=device,\n", 468 | " clip_denoised=True,\n", 469 | " progress=True,\n", 470 | " model_kwargs=model_kwargs,\n", 471 | " cond_fn=cond_fn,\n", 472 | ")\n", 473 | "model.del_cache()\n", 474 | "\n", 475 | "# Show the output\n", 476 | "show_images(samples)\n", 477 | "\n", 478 | "##############################\n", 479 | "# Upsample the 64x64 samples #\n", 480 | "##############################\n", 481 | "\n", 482 | "tokens = model_up.tokenizer.encode(prompt)\n", 483 | "tokens, mask = model_up.tokenizer.padded_tokens_and_mask(\n", 484 | " tokens, options_up['text_ctx']\n", 485 | ")\n", 486 | "\n", 487 | "# Create the model conditioning dict.\n", 488 | "model_kwargs = dict(\n", 489 | " # Low-res image to upsample.\n", 490 | " low_res=((samples+1)*127.5).round()/127.5 - 1,\n", 491 | "\n", 492 | " # Text tokens\n", 493 | " tokens=th.tensor(\n", 494 | " [tokens] * batch_size, device=device\n", 495 | " ),\n", 496 | " mask=th.tensor(\n", 497 | " [mask] * batch_size,\n", 498 | " dtype=th.bool,\n", 499 | " device=device,\n", 500 | " ),\n", 501 | ")\n", 502 | "\n", 503 | "# Sample from the base model.\n", 504 | "model_up.del_cache()\n", 505 | "up_shape = (batch_size, 3, options_up[\"image_size\"], options_up[\"image_size\"])\n", 506 | "up_samples = diffusion_up.ddim_sample_loop(\n", 507 | " model_up,\n", 508 | " up_shape,\n", 509 | " noise=th.randn(up_shape, device=device) * upsample_temp,\n", 510 | " device=device,\n", 511 | " clip_denoised=True,\n", 512 | " progress=True,\n", 513 | " model_kwargs=model_kwargs,\n", 514 | " cond_fn=None,\n", 515 | ")[:batch_size]\n", 516 | "model_up.del_cache()\n", 517 | "\n", 518 | "# Show the output\n", 519 | "show_images(up_samples)" 520 | ] 521 | }, 522 | { 523 | "cell_type": "code", 524 | "execution_count": null, 525 | "metadata": {}, 526 | "outputs": [], 527 | "source": [ 528 | "##############################\n", 529 | "# Sample from the base model #\n", 530 | "##############################\n", 531 | "\n", 532 | "# Create the text tokens to feed to the model.\n", 533 | "tokens = model.tokenizer.encode(prompt)\n", 534 | "tokens, mask = model.tokenizer.padded_tokens_and_mask(\n", 535 | " tokens, options['text_ctx']\n", 536 | ")\n", 537 | "\n", 538 | "# Create the classifier-free guidance tokens (empty)\n", 539 | "full_batch_size = batch_size * 2\n", 540 | "uncond_tokens, uncond_mask = model.tokenizer.padded_tokens_and_mask(\n", 541 | " [], options['text_ctx']\n", 542 | ")\n", 543 | "\n", 544 | "# Pack the tokens together into model kwargs.\n", 545 | "model_kwargs = dict(\n", 546 | " tokens=th.tensor(\n", 547 | " [tokens] * batch_size + [uncond_tokens] * batch_size, device=device\n", 548 | " ),\n", 549 | " mask=th.tensor(\n", 550 | " [mask] * batch_size + [uncond_mask] * batch_size,\n", 551 | " dtype=th.bool,\n", 552 | " device=device,\n", 553 | " ),\n", 554 | "\n", 555 | " # Masked inpainting image\n", 556 | " inpaint_image=(source_image_64 * source_mask_64).repeat(full_batch_size, 1, 1, 1).to(device),\n", 557 | " inpaint_mask=source_mask_64.repeat(full_batch_size, 1, 1, 1).to(device),\n", 558 | ")\n", 559 | "\n", 560 | "# Create an classifier-free guidance sampling function\n", 561 | "def model_fn(x_t, ts, **kwargs):\n", 562 | " half = x_t[: len(x_t) // 2]\n", 563 | " combined = th.cat([half, half], dim=0)\n", 564 | " model_out = model(combined, ts, **kwargs)\n", 565 | " eps, rest = model_out[:, :3], model_out[:, 3:]\n", 566 | " cond_eps, uncond_eps = th.split(eps, len(eps) // 2, dim=0)\n", 567 | " half_eps = uncond_eps + guidance_scale * (cond_eps - uncond_eps)\n", 568 | " eps = th.cat([half_eps, half_eps], dim=0)\n", 569 | " return th.cat([eps, rest], dim=1)\n", 570 | "\n", 571 | "def denoised_fn(x_start):\n", 572 | " # Force the model to have the exact right x_start predictions\n", 573 | " # for the part of the image which is known.\n", 574 | " return (\n", 575 | " x_start * (1 - model_kwargs['inpaint_mask'])\n", 576 | " + model_kwargs['inpaint_image'] * model_kwargs['inpaint_mask']\n", 577 | " )\n", 578 | "\n", 579 | "# Sample from the base model.\n", 580 | "model.del_cache()\n", 581 | "samples = diffusion.p_sample_loop(\n", 582 | " model_fn,\n", 583 | " (full_batch_size, 3, options[\"image_size\"], options[\"image_size\"]),\n", 584 | " device=device,\n", 585 | " clip_denoised=True,\n", 586 | " progress=True,\n", 587 | " model_kwargs=model_kwargs,\n", 588 | " cond_fn=None,\n", 589 | " denoised_fn=denoised_fn,\n", 590 | ")[:batch_size]\n", 591 | "model.del_cache()\n", 592 | "\n", 593 | "# Show the output\n", 594 | "show_images(samples)" 595 | ] 596 | } 597 | ], 598 | "metadata": { 599 | "accelerator": "GPU", 600 | "interpreter": { 601 | "hash": "e7d6e62d90e7e85f9a0faa7f0b1d576302d7ae6108e9fe361594f8e1c8b05781" 602 | }, 603 | "kernelspec": { 604 | "display_name": "default:Python", 605 | "language": "python", 606 | "name": "conda-env-default-py" 607 | }, 608 | "language_info": { 609 | "codemirror_mode": { 610 | "name": "ipython", 611 | "version": 3 612 | }, 613 | "file_extension": ".py", 614 | "mimetype": "text/x-python", 615 | "name": "python", 616 | "nbconvert_exporter": "python", 617 | "pygments_lexer": "ipython3", 618 | "version": "3.9.7" 619 | } 620 | }, 621 | "nbformat": 4, 622 | "nbformat_minor": 4 623 | } 624 | --------------------------------------------------------------------------------