diff --git a/docs/source/multimodal/api.rst b/docs/source/multimodal/api.rst index ef517d6bdd5a..63ce477273b3 100644 --- a/docs/source/multimodal/api.rst +++ b/docs/source/multimodal/api.rst @@ -10,7 +10,7 @@ Model Classes :members: __init__, configure_optimizers -.. autoclass:: nemo.collections.multimodal.models.stable_diffusion.ldm.ddpm.MegatronLatentDiffusion +.. autoclass:: nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.ddpm.MegatronLatentDiffusion :show-inheritance: :no-members: :members: __init__, training_step, validation_step, setup, build_train_valid_test_datasets @@ -49,7 +49,7 @@ Modules :show-inheritance: :no-members: -.. autoclass:: nemo.collections.multimodal.models.stable_diffusion.ldm.autoencoder.AutoencoderKL +.. autoclass:: nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.autoencoder.AutoencoderKL :show-inheritance: :no-members: :members: __init__, encode, decode diff --git a/docs/source/multimodal/mllm/checkpoint.rst b/docs/source/multimodal/mllm/checkpoint.rst index 8ccb520bda4b..9ee1042588b1 100644 --- a/docs/source/multimodal/mllm/checkpoint.rst +++ b/docs/source/multimodal/mllm/checkpoint.rst @@ -108,7 +108,7 @@ Adjust model parallelism with: --target_tensor_model_parallel_size=??? \ --pipeline_model_parallel_size=??? \ --target_pipeline_model_parallel_size=??? \ - --model_class="nemo.collections.multimodal.models.neva.neva_model.MegatronNevaModel" \ + --model_class="nemo.collections.multimodal.models.multimodal_llm.neva.neva_model.MegatronNevaModel" \ --precision=32 \ --tokenizer_model_path=/path/to/tokenizer.model \ --tp_conversion_only diff --git a/docs/source/multimodal/text2img/insp2p.rst b/docs/source/multimodal/text2img/insp2p.rst index 20e68f5742e3..b5a04d69fd2d 100644 --- a/docs/source/multimodal/text2img/insp2p.rst +++ b/docs/source/multimodal/text2img/insp2p.rst @@ -6,7 +6,7 @@ Model Introduction InstructPix2Pix [InstructPix2Pix]_ :cite:`mm-models-insp2p` offers a unique approach to image editing using human-written instructions. Given an input image and a textual directive, the model adjusts the image according to the provided instructions. NeMo Multimodal presents a training pipeline for this conditional diffusion model, utilizing a dataset generated by harnessing the strengths of two prominent pretrained models: a language model (GPT-3) and a text-to-image model (Stable Diffusion). The InstructPix2Pix model operates swiftly, editing images within seconds, eliminating the need for per-example fine-tuning or inversion. It has demonstrated remarkable results across a wide variety of input images and written instructions. -Built upon the Stable Diffusion framework, NeMo's InstructPix2Pix shares a similar architecture with Stable Diffusion (refer to :doc:`Stable Diffusion <./sd>`). What sets it apart is its unique training dataset and the combined guidance from both image and text prompts. Specifically, InstructPix2pix ::class::``nemo.collections.multimodal.models.instruct_pix2pix.ldm.ddpm_edit.MegatronLatentDiffusionEdit`` is derived directly from Stable Diffusion's ::class::``nemo.collections.multimodal.models.stable_diffusion.ldm.ddpm.MegatronLatentDiffusion``, with alterations to accommodate the dataset and provide support for dual guidance. +Built upon the Stable Diffusion framework, NeMo's InstructPix2Pix shares a similar architecture with Stable Diffusion (refer to :doc:`Stable Diffusion <./sd>`). What sets it apart is its unique training dataset and the combined guidance from both image and text prompts. Specifically, InstructPix2pix ::class::``nemo.collections.multimodal.models.instruct_pix2pix.ldm.ddpm_edit.MegatronLatentDiffusionEdit`` is derived directly from Stable Diffusion's ::class::``nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.ddpm.MegatronLatentDiffusion``, with alterations to accommodate the dataset and provide support for dual guidance. Training Dataset -------------------- diff --git a/docs/source/multimodal/text2img/sd.rst b/docs/source/multimodal/text2img/sd.rst index 23865058ab9b..ffadeda61637 100644 --- a/docs/source/multimodal/text2img/sd.rst +++ b/docs/source/multimodal/text2img/sd.rst @@ -33,7 +33,7 @@ The VAE configuration is defined under **first_stage_config**. .. code-block:: yaml first_stage_config: - _target_: nemo.collections.multimodal.models.stable_diffusion.ldm.autoencoder.AutoencoderKL + _target_: nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.autoencoder.AutoencoderKL from_pretrained: /path/to/vae.bin embed_dim: 4 monitor: val/rec_loss diff --git a/examples/multimodal/multimodal_llm/neva/conf/neva_inference.yaml b/examples/multimodal/multimodal_llm/neva/conf/neva_inference.yaml index 6ff8e889aba1..c822237f8fc9 100644 --- a/examples/multimodal/multimodal_llm/neva/conf/neva_inference.yaml +++ b/examples/multimodal/multimodal_llm/neva/conf/neva_inference.yaml @@ -11,6 +11,7 @@ inference: compute_logprob: False # a flag used to compute logprob of all the input text, a very special case of running inference, default False end_strings: ["","",] # generation will stop when one of these tokens is generated images_base_path: /pwd/images + insert_image_token: null # `left` or `right` or `null` trainer: devices: 8 @@ -24,7 +25,7 @@ tensor_model_parallel_size: 8 pipeline_model_parallel_size: 1 pipeline_model_parallel_split_rank: 0 # used for encoder and decoder model (0 for others) neva_model_file: /pwd/nemo_experiments/nemo_llava.nemo #neva_22b_tp8_finetuned_v1.nemo neva_8b_tp4_finetuned_v1.nemo -llm_model_file: null +base_model_file: null checkpoint_dir: null #/pwd/nemo_multimodal/nemo_experiments/nemo_llava_finetune/checkpoints # checkpoint file dir. This is used to load the PTL checkpoint generated during the Kosmos training checkpoint_name: null #megatron_clip--val_loss=0.41-step=13499-consumed_samples=431904.0.ckpt # PTL checkpoint file name, only used for PTL checkpoint loading hparams_file: null #/pwd/nemo_multimodal/nemo_experiments/nemo_llava_finetune/version_0/hparams.yaml # model configuration file, only used for PTL checkpoint loading diff --git a/examples/multimodal/multimodal_llm/neva/conf/neva_peft.yaml b/examples/multimodal/multimodal_llm/neva/conf/neva_peft.yaml index 36e706635b97..add113cdc539 100644 --- a/examples/multimodal/multimodal_llm/neva/conf/neva_peft.yaml +++ b/examples/multimodal/multimodal_llm/neva/conf/neva_peft.yaml @@ -209,7 +209,7 @@ model: optim: name: fused_adam - lr: 2e-5 + lr: 2e-4 weight_decay: 0. betas: - 0.9 diff --git a/examples/multimodal/multimodal_llm/neva/convert_hf_llava_to_neva.py b/examples/multimodal/multimodal_llm/neva/convert_hf_llava_to_neva.py index 82536e32c370..c9263ea85bbf 100644 --- a/examples/multimodal/multimodal_llm/neva/convert_hf_llava_to_neva.py +++ b/examples/multimodal/multimodal_llm/neva/convert_hf_llava_to_neva.py @@ -18,7 +18,8 @@ python convert_hf_llava_to_neva.py \ --in-file \ --out-file \ - --tokenizer-model + --tokenizer-model \ + --conv-template llama_2 # nvgpt, llama_2, v1 (vicuna) """ import os @@ -49,6 +50,13 @@ def get_args(): "--in-file", type=str, default=None, required=True, help="Path to Huggingface LLaMA checkpoints", ) parser.add_argument("--out-file", type=str, default=None, required=True, help="Path to output .nemo file.") + parser.add_argument( + "--conv-template", + type=str, + default="llama_2", + required=False, + help="Conversation template: nvgpt, llama_2, v1 (vicuna)", + ) parser.add_argument( "--tokenizer-model", type=str, default=None, required=False, help="Path to sentencepiece tokenizer model." ) @@ -121,6 +129,8 @@ def load_config(args, llava_config): nemo_config.num_query_groups = llava_config['num_key_value_heads'] nemo_config.use_cpu_initialization = True nemo_config.activation = 'fast-swiglu' + nemo_config.data.conv_template = args.conv_template + nemo_config.mm_cfg.model_type = args.conv_template if args.tokenizer_model is None: nemo_config.tokenizer.model = llava_config['tokenizer_model'] else: diff --git a/examples/multimodal/multimodal_llm/neva/eval/gradio_cli.py b/examples/multimodal/multimodal_llm/neva/eval/gradio_cli.py new file mode 100644 index 000000000000..4f2136eac83a --- /dev/null +++ b/examples/multimodal/multimodal_llm/neva/eval/gradio_cli.py @@ -0,0 +1,41 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. 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 base64 + +import requests + +# URL of the Gradio server +url = 'http://localhost:8890/api/predict/' + +# Prepare the text data +text_data = 'Describe this image please.' + +# Prepare the image data +with open("/path/to/images/001.jpg", "rb") as image_file: + encoded_string = base64.b64encode(image_file.read()).decode() + +# Data to send +data = {'data': [text_data, encoded_string]} + +# Sending a POST request to the Gradio server +response = requests.post(url, json=data) + +# Checking if the request was successful +if response.status_code == 200: + # Parsing the response + response_data = response.json() + print("Response from server:", response_data) +else: + print("Failed to get a response from the server, status code:", response.status_code) diff --git a/examples/multimodal/multimodal_llm/neva/eval/gradio_server.py b/examples/multimodal/multimodal_llm/neva/eval/gradio_server.py new file mode 100644 index 000000000000..b1308a7b0d3c --- /dev/null +++ b/examples/multimodal/multimodal_llm/neva/eval/gradio_server.py @@ -0,0 +1,108 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. 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 base64 +import io + +import gradio as gr +import PIL.Image +from omegaconf import OmegaConf + +from nemo.collections.multimodal.parts.utils import create_neva_model_and_processor + +CFG_STRING = """ +trainer: + devices: 1 + num_nodes: 1 + accelerator: gpu + logger: False # logger provided by exp_manager + precision: bf16 # 16, 32, or bf16 + +inference: + greedy: False # Whether or not to use sampling ; use greedy decoding otherwise + top_k: 0 # The number of highest probability vocabulary tokens to keep for top-k-filtering. + top_p: 0.9 # If set to float < 1, only the most probable tokens with probabilities that add up to top_p or higher are kept for generation. + temperature: 0.2 # sampling temperature + add_BOS: False # add the bos token at the begining of the prompt + tokens_to_generate: 256 # The minimum length of the sequence to be generated. + all_probs: False # whether return the log prob for all the tokens in vocab + repetition_penalty: 1.2 # The parameter for repetition penalty. 1.0 means no penalty. + min_tokens_to_generate: 0 # The minimum length of the sequence to be generated. + compute_logprob: False # a flag used to compute logprob of all the input text, a very special case of running inference, default False + end_strings: ["","",] # generation will stop when one of these tokens is generated + images_base_path: /pwd/images + insert_image_token: null # `left` or `right` or `null` + +cluster_type: BCP +tensor_model_parallel_size: 1 +pipeline_model_parallel_size: 1 +pipeline_model_parallel_split_rank: 0 # used for encoder and decoder model (0 for others) + +neva_model_file: /pwd/nemo_experiments/nemo_llava.nemo #neva_22b_tp8_finetuned_v1.nemo neva_8b_tp4_finetuned_v1.nemo +base_model_file: null +checkpoint_dir: null #/pwd/nemo_multimodal/nemo_experiments/nemo_llava_finetune/checkpoints # checkpoint file dir. This is used to load the PTL checkpoint generated during the Kosmos training +checkpoint_name: null #megatron_clip--val_loss=0.41-step=13499-consumed_samples=431904.0.ckpt # PTL checkpoint file name, only used for PTL checkpoint loading +hparams_file: null #/pwd/nemo_multimodal/nemo_experiments/nemo_llava_finetune/version_0/hparams.yaml # model configuration file, only used for PTL checkpoint loading +""" + +cfg = OmegaConf.create(CFG_STRING) +cfg.neva_model_file = "/path/to/llava-v1.5-7b.nemo" +model, image_processor = create_neva_model_and_processor(cfg) + + +def predict(prompt, image_base64=None): + input_data = {"prompt": prompt} + if image_base64 is not None: + image_data = base64.b64decode(image_base64) + # image = PIL.Image.fromarray(image) + image = PIL.Image.open(io.BytesIO(image_data)) + input_data["image"] = image_processor(image) + + length_params: LengthParam = { + "max_length": cfg.inference.tokens_to_generate, + "min_length": cfg.inference.min_tokens_to_generate, + } + sampling_params: SamplingParam = { + "use_greedy": cfg.inference.greedy, + "temperature": cfg.inference.temperature, + "top_k": cfg.inference.top_k, + "top_p": cfg.inference.top_p, + "repetition_penalty": cfg.inference.repetition_penalty, + "add_BOS": cfg.inference.add_BOS, + "all_probs": cfg.inference.all_probs, + "compute_logprob": cfg.inference.compute_logprob, + "end_strings": cfg.inference.end_strings, + } + + # Generate model responses + responses = model.generate( + input_prompts=[input_data], # Adjust based on your model's requirements + length_params=length_params, # Define these parameters as in your original code + sampling_params=sampling_params, # Define these parameters as in your original code + inference_config=cfg, + ) + + return responses[0]["clean_response"] + + +iface = gr.Interface( + fn=predict, + inputs=[gr.Textbox(), gr.Textbox()], + outputs="text", + title="Multimodal Model Inference", + description="Enter a prompt and optionally upload an image for model inference.", +) + +if __name__ == "__main__": + iface.launch(server_port=8890, share=False) diff --git a/examples/multimodal/multimodal_llm/neva/eval/vqa_science.py b/examples/multimodal/multimodal_llm/neva/eval/vqa_science.py new file mode 100644 index 000000000000..8ea267ac8116 --- /dev/null +++ b/examples/multimodal/multimodal_llm/neva/eval/vqa_science.py @@ -0,0 +1,176 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. 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 argparse +import json +import math +import os + +import shortuuid +from omegaconf import OmegaConf +from tqdm import tqdm + +from nemo.collections.multimodal.parts.utils import create_neva_model_and_processor +from nemo.collections.nlp.modules.common.transformer.text_generation import LengthParam, SamplingParam +from nemo.utils.get_rank import is_global_rank_zero + +CFG_STRING = """ +trainer: + devices: 1 + num_nodes: 1 + accelerator: gpu + logger: False # logger provided by exp_manager + precision: bf16 # 16, 32, or bf16 + +inference: + greedy: True # Whether or not to use sampling ; use greedy decoding otherwise + top_k: 0 # The number of highest probability vocabulary tokens to keep for top-k-filtering. + top_p: 0.9 # If set to float < 1, only the most probable tokens with probabilities that add up to top_p or higher are kept for generation. + temperature: 0.2 # sampling temperature + add_BOS: True # add the bos token at the begining of the prompt + tokens_to_generate: 64 # The minimum length of the sequence to be generated. + all_probs: False # whether return the log prob for all the tokens in vocab + repetition_penalty: 1.2 # The parameter for repetition penalty. 1.0 means no penalty. + min_tokens_to_generate: 0 # The minimum length of the sequence to be generated. + compute_logprob: False # a flag used to compute logprob of all the input text, a very special case of running inference, default False + end_strings: ["","",] # generation will stop when one of these tokens is generated + images_base_path: /pwd/images + insert_image_token: null # `left` or `right` or `null` + +cluster_type: BCP +tensor_model_parallel_size: 1 +pipeline_model_parallel_size: 1 +pipeline_model_parallel_split_rank: 0 # used for encoder and decoder model (0 for others) + +neva_model_file: /pwd/nemo_experiments/nemo_llava.nemo #neva_22b_tp8_finetuned_v1.nemo neva_8b_tp4_finetuned_v1.nemo +base_model_file: null +checkpoint_dir: null #/pwd/nemo_multimodal/nemo_experiments/nemo_llava_finetune/checkpoints # checkpoint file dir. This is used to load the PTL checkpoint generated during the Kosmos training +checkpoint_name: null #megatron_clip--val_loss=0.41-step=13499-consumed_samples=431904.0.ckpt # PTL checkpoint file name, only used for PTL checkpoint loading +hparams_file: null #/pwd/nemo_multimodal/nemo_experiments/nemo_llava_finetune/version_0/hparams.yaml # model configuration file, only used for PTL checkpoint loading +""" + + +def split_list(lst, n): + """Split a list into n (roughly) equal-sized chunks""" + chunk_size = math.ceil(len(lst) / n) # integer division + return [lst[i : i + chunk_size] for i in range(0, len(lst), chunk_size)] + + +def get_chunk(lst, n, k): + chunks = split_list(lst, n) + return chunks[k] + + +def eval_model(args): + # Model + cfg = OmegaConf.create(CFG_STRING) + cfg.neva_model_file = args.model_path + cfg.base_model_file = args.model_base + cfg.inference.images_base_path = args.image_folder + cfg.tensor_model_parallel_size = args.tp + cfg.trainer.devices = args.tp + + model, image_processor = create_neva_model_and_processor(cfg) + length_params: LengthParam = { + "max_length": cfg.inference.tokens_to_generate, + "min_length": cfg.inference.min_tokens_to_generate, + } + sampling_params: SamplingParam = { + "use_greedy": cfg.inference.greedy, + "temperature": cfg.inference.temperature, + "top_k": cfg.inference.top_k, + "top_p": cfg.inference.top_p, + "repetition_penalty": cfg.inference.repetition_penalty, + "add_BOS": cfg.inference.add_BOS, + "all_probs": cfg.inference.all_probs, + "compute_logprob": cfg.inference.compute_logprob, + "end_strings": cfg.inference.end_strings, + } + + questions = json.load(open(os.path.expanduser(args.question_file), "r")) + questions = get_chunk(questions, args.num_chunks, args.chunk_idx) + answers_file = os.path.expanduser(args.answers_file) + os.makedirs(os.path.dirname(answers_file), exist_ok=True) + ans_file = open(answers_file, "w") + for i, line in enumerate(tqdm(questions, disable=(not is_global_rank_zero()))): + idx = line["id"] + question = line['conversations'][0] + qs = question['value'].replace('', '').strip() + cur_prompt = qs + + if 'image' in line: + cur_prompt = qs = '' + cur_prompt + line['image'] = image_processor(os.path.join(cfg.inference.images_base_path, line['image'])) + + if args.single_pred_prompt: + qs = qs + '\n' + "Answer with the option's letter from the given choices directly." + cur_prompt = cur_prompt + '\n' + "Answer with the option's letter from the given choices directly." + + responses = model.generate( + input_prompts=[dict(prompt=qs, image=line.get('image', None))], + length_params=length_params, + sampling_params=sampling_params, + inference_config=cfg, + ) + # import pdb; pdb.set_trace() + outputs = responses[0]["clean_response"] + + # prompt for answer + if args.answer_prompter: + outputs_reasoning = outputs + + responses = model.generate( + input_prompts=[prompt + outputs_reasoning + ' ###\nANSWER:'], + length_params=length_params, + sampling_params=sampling_params, + inference_config=cfg, + ) + outputs = responses[0]["clean_response"] + outputs = outputs_reasoning + '\n The answer is ' + outputs + + ans_id = shortuuid.uuid() + ans_file.write( + json.dumps( + { + "question_id": idx, + "prompt": cur_prompt, + "text": outputs, + "answer_id": ans_id, + "model_id": args.model_path, + "metadata": {}, + } + ) + + "\n" + ) + ans_file.flush() + ans_file.close() + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--model-path", type=str, default="facebook/opt-350m") + parser.add_argument("--model-base", type=str, default=None) + parser.add_argument("--image-folder", type=str, default="") + parser.add_argument("--question-file", type=str, default="tables/question.json") + parser.add_argument("--answers-file", type=str, default="answer.jsonl") + parser.add_argument("--conv-mode", type=str, default="llava_v0") + parser.add_argument("--tp", type=int, default=1) + parser.add_argument("--num-chunks", type=int, default=1) + parser.add_argument("--chunk-idx", type=int, default=0) + parser.add_argument("--temperature", type=float, default=0.2) + parser.add_argument("--answer-prompter", action="store_true") + parser.add_argument("--single-pred-prompt", action="store_true") + args = parser.parse_args() + + eval_model(args) diff --git a/examples/multimodal/multimodal_llm/neva/neva_evaluation.py b/examples/multimodal/multimodal_llm/neva/neva_evaluation.py index a3ee54937161..545a634ac7fb 100644 --- a/examples/multimodal/multimodal_llm/neva/neva_evaluation.py +++ b/examples/multimodal/multimodal_llm/neva/neva_evaluation.py @@ -14,21 +14,12 @@ import json import os - import torch -from omegaconf import OmegaConf, open_dict -from pytorch_lightning.plugins.environments import TorchElasticEnvironment -from pytorch_lightning.trainer.trainer import Trainer from torch.utils.data import Dataset -from nemo.collections.multimodal.models.multimodal_llm.neva.neva_model import MegatronNevaModel -from nemo.collections.nlp.modules.common.megatron.megatron_init import fake_initialize_model_parallel +from nemo.collections.multimodal.parts.utils import create_neva_model_and_processor from nemo.collections.nlp.modules.common.transformer.text_generation import LengthParam, SamplingParam -from nemo.collections.nlp.parts.nlp_overrides import NLPDDPStrategy, NLPSaveRestoreConnector -from nemo.collections.nlp.parts.peft_config import PEFT_CONFIG_MAP from nemo.core.config import hydra_runner -from nemo.utils.app_state import AppState -from nemo.utils.model_utils import inject_model_parallel_rank try: @@ -40,105 +31,6 @@ HAVE_AMMO = False - -""" -This is the script to run GPT text generation. - -Usage: - Assume the model has TP=1, PP=1 in the following use cases. - a. run greedy inference from a nemo file: - python neva_evaluation.py \ - neva_model_file=PATH_TO_MODEL \ - inference.greedy=True \ - inference.add_BOS=True \ - trainer.devices=1 \ - trainer.num_nodes=1 \ - tensor_model_parallel_size=-1 \ - pipeline_model_parallel_size=-1 \ - prompts=[prompt1,prompt2] - - b. run greedy inference from a PTL checkpoint file: - python neva_evaluation.py \ - checkpoint_dir=PATH_TO_CHECKPOINT_FILE \ - checkpoint_name=CHECKPOINT_FILE_NAME \ - hparams_file=HPARAMS_FILE \ - inference.greedy=True \ - inference.add_BOS=True \ - trainer.devices=1 \ - trainer.num_nodes=1 \ - tensor_model_parallel_size=-1 \ - pipeline_model_parallel_size=-1 \ - prompts=[prompt1,prompt2] - - c. run top_p inference from a nemo file: - python neva_evaluation.py \ - neva_model_file=PATH_TO_MODEL \ - inference.greedy=False \ - inference.top_k=0 \ - inference.top_p=0.9 \ - inference.repetition_penalty=1.2 \ - inference.add_BOS=True \ - trainer.devices=1 \ - trainer.num_nodes=1 \ - tensor_model_parallel_size=-1 \ - pipeline_model_parallel_size=-1 \ - prompts=[prompt1,prompt2] - - d. If you don't need to generate tokens and need model to compute logprobs: - python neva_evaluation.py \ - neva_model_file=PATH_TO_MODEL \ - inference.compute_logprob=True \ - trainer.devices=1 \ - trainer.num_nodes=1 \ - tensor_model_parallel_size=-1 \ - pipeline_model_parallel_size=-1 \ - prompts=[text to get logprob] - - e. Launch the inference server - python neva_evaluation.py \ - neva_model_file=PATH_TO_MODEL \ - trainer.devices=1 \ - trainer.num_nodes=1 \ - tensor_model_parallel_size=-1 \ - pipeline_model_parallel_size=-1 \ - server=True - - To send a request to the server, here is one example code: - ```python - import json - import requests - - batch_size = 8 - port_num = 5555 - headers = {"Content-Type": "application/json"} - - - def request_data(data): - resp = requests.put('http://localhost:{}/generate'.format(port_num), - data=json.dumps(data), - headers=headers) - sentences = resp.json()['sentences'] - return sentences - - - data = { - "sentences": [""] * batch_size, - "images" : [] * batch_size, - "tokens_to_generate": 300, - "temperature": 1.0, - "add_BOS": True, - "top_k": 0, - "top_p": 0.9, - "greedy": False, - "all_probs": False, - "repetition_penalty": 1.2, - "min_tokens_to_generate": 2, - } - - sentences = request_data(data) - ``` -""" - if not torch.cuda.is_available(): raise EnvironmentError("GPU is needed for the inference") @@ -157,100 +49,7 @@ def __getitem__(self, idx): @hydra_runner(config_path="conf", config_name="neva_inference") def main(cfg) -> None: - - plugins = [] - if cfg.get('cluster_type', None) == 'BCP': - plugins.append(TorchElasticEnvironment()) - # trainer required for restoring model parallel models - trainer = Trainer(plugins=plugins, strategy=NLPDDPStrategy(), **cfg.trainer) - - if ( - cfg.tensor_model_parallel_size < 0 - or cfg.pipeline_model_parallel_size < 0 - or cfg.get('pipeline_model_parallel_split_rank', -1) < 0 - ): - model_config = MegatronNevaModel.restore_from( - restore_path=cfg.neva_model_file, trainer=trainer, return_config=True, - ) - - with open_dict(cfg): - cfg.tensor_model_parallel_size = model_config.get('tensor_model_parallel_size', 1) - cfg.pipeline_model_parallel_size = model_config.get('pipeline_model_parallel_size', 1) - cfg.pipeline_model_parallel_split_rank = model_config.get('pipeline_model_parallel_split_rank', 0) - - assert ( - cfg.trainer.devices * cfg.trainer.num_nodes - == cfg.tensor_model_parallel_size * cfg.pipeline_model_parallel_size - ), "devices * num_nodes should equal tensor_model_parallel_size * pipeline_model_parallel_size" - - if cfg.neva_model_file: - save_restore_connector = NLPSaveRestoreConnector() - if os.path.isdir(cfg.neva_model_file): - save_restore_connector.model_extracted_dir = cfg.neva_model_file - - neva_cfg = MegatronNevaModel.restore_from( - restore_path=cfg.neva_model_file, - trainer=trainer, - return_config=True, - save_restore_connector=save_restore_connector, - ) - OmegaConf.set_struct(neva_cfg, True) - with open_dict(neva_cfg): - neva_cfg.sequence_parallel = False - neva_cfg.activations_checkpoint_granularity = None - neva_cfg.activations_checkpoint_method = None - neva_cfg.precision = trainer.precision - neva_cfg.mm_cfg.llm.from_pretrained = cfg.get('llm_model_file', None) - # neva_cfg.mm_cfg.vision_encoder.from_pretrained = None - - model = MegatronNevaModel.restore_from( - restore_path=cfg.neva_model_file, - trainer=trainer, - override_config_path=neva_cfg, - save_restore_connector=save_restore_connector, - ) - if neva_cfg.get('peft') is not None: - peft_cfg_cls = PEFT_CONFIG_MAP[neva_cfg.peft.peft_scheme] - if peft_cfg_cls is not None: - model.load_adapters(cfg.neva_model_file, peft_cfg_cls(neva_cfg)) - - elif cfg.checkpoint_dir: - app_state = AppState() - if cfg.tensor_model_parallel_size > 1 or cfg.pipeline_model_parallel_size > 1: - app_state.model_parallel_size = cfg.tensor_model_parallel_size * cfg.pipeline_model_parallel_size - app_state.tensor_model_parallel_size = cfg.tensor_model_parallel_size - app_state.pipeline_model_parallel_size = cfg.pipeline_model_parallel_size - ( - app_state.tensor_model_parallel_rank, - app_state.pipeline_model_parallel_rank, - app_state.model_parallel_size, - app_state.data_parallel_size, - app_state.pipeline_model_parallel_split_rank, - app_state.virtual_pipeline_model_parallel_rank, - ) = fake_initialize_model_parallel( - world_size=app_state.model_parallel_size, - rank=trainer.global_rank, - tensor_model_parallel_size_=cfg.tensor_model_parallel_size, - pipeline_model_parallel_size_=cfg.pipeline_model_parallel_size, - pipeline_model_parallel_split_rank_=cfg.pipeline_model_parallel_split_rank, - ) - checkpoint_path = inject_model_parallel_rank(os.path.join(cfg.checkpoint_dir, cfg.checkpoint_name)) - # TODO: This wont work properly (We need to set model.llm.from_pretrained model.vision.from_pretrained to nul) - model = MegatronNevaModel.load_from_checkpoint(checkpoint_path, hparams_file=cfg.hparams_file, trainer=trainer) - else: - raise ValueError("need at least a nemo file or checkpoint dir") - - model.freeze() - - # Have to turn off activations_checkpoint_method for inference - try: - model.model.language_model.encoder.activations_checkpoint_method = None - except AttributeError: - pass - try: - model.model.module.language_model.encoder.activations_checkpoint_method = None - except AttributeError: - pass + model, image_processor = create_neva_model_and_processor(cfg) length_params: LengthParam = { "max_length": cfg.inference.tokens_to_generate, @@ -275,6 +74,16 @@ def main(cfg) -> None: final_prompts = [] for line in lines: prompt_dict = json.loads(line) + assert 'prompt' in prompt_dict or 'text' in prompt_dict + if 'prompt' not in prompt_dict: + prompt_dict['prompt'] = prompt_dict['text'] + if cfg.inference.insert_image_token == 'left': + prompt_dict['prompt'] = '' + prompt_dict['prompt'] + elif cfg.inference.insert_image_token == 'right': + prompt_dict['prompt'] = prompt_dict['prompt'] + '' + if 'image' in prompt_dict: + prompt_dict['image_path'] = prompt_dict['image'] + prompt_dict['image'] = image_processor(os.path.join(cfg.inference.images_base_path, prompt_dict['image'])) final_prompts.append(prompt_dict) responses = model.generate( @@ -316,27 +125,18 @@ def forward_loop(): prompt['full_text'] = response["clean_text"] prompt['text'] = response["clean_response"] prompt['model_id'] = cfg.neva_model_file - prompt['answer_id'] = 0 - prompt['metadata'] = {} + if 'image_path' in prompt: + prompt['image'] = prompt.pop('image_path') + if 'answer_id' not in prompt: + prompt['answer_id'] = 0 + if 'metadata' not in prompt: + prompt['metadata'] = {} results.append(prompt) with open(cfg.output_file, 'w') as f: for result in results: f.write(json.dumps(result) + '\n') - """ - # Second method of running text generation, call trainer.predict - ds = RequestDataSet(final_prompts) - request_dl = DataLoader(dataset=ds, batch_size=1) - config = OmegaConf.to_container(cfg.inference) - model.set_inference_config(config) - response = trainer.predict(model, request_dl) - - print("***************************") - print(response) - print("***************************") - """ - if __name__ == '__main__': main() # noqa pylint: disable=no-value-for-parameter diff --git a/examples/multimodal/text_to_image/controlnet/controlnet_infer.py b/examples/multimodal/text_to_image/controlnet/controlnet_infer.py index 4cdf922f8211..a33f3fc185ad 100644 --- a/examples/multimodal/text_to_image/controlnet/controlnet_infer.py +++ b/examples/multimodal/text_to_image/controlnet/controlnet_infer.py @@ -20,7 +20,6 @@ import torch from PIL import Image -from nemo.collections.multimodal.models.text_to_image.controlnet import get_preprocessing_function from nemo.collections.multimodal.models.text_to_image.controlnet.controlnet import MegatronControlNet from nemo.collections.multimodal.models.text_to_image.stable_diffusion.samplers.ddim import DDIMSampler from nemo.collections.multimodal.models.text_to_image.stable_diffusion.samplers.plms import PLMSSampler @@ -30,10 +29,6 @@ def get_control_input(image_path, batch_size, hint_image_size, control_image_preprocess=None): image = cv2.imread(image_path) - if control_image_preprocess: - # More applications will be supported here - process = get_preprocessing_function(control_image_preprocess) - image = process(image) image = cv2.resize(image, (hint_image_size, hint_image_size)) control = torch.from_numpy(image).float() / 255.0 control = torch.stack([control for _ in range(batch_size)], dim=0) diff --git a/examples/multimodal/text_to_image/dreambooth/conf/dreambooth_infer.yaml b/examples/multimodal/text_to_image/dreambooth/conf/dreambooth_infer.yaml index fc8d35443767..02faba0c65f6 100644 --- a/examples/multimodal/text_to_image/dreambooth/conf/dreambooth_infer.yaml +++ b/examples/multimodal/text_to_image/dreambooth/conf/dreambooth_infer.yaml @@ -15,16 +15,13 @@ infer: seed: 123 prompts: - 'a photo of a sks dog' - - 'a photo of a sks dog in the Acropolis' - - 'a photo of a sks dog in front of eiffel tower' - - 'a photo of sks dog sleeping' - - 'a photo of a sks dog riding a bike' + - 'a photo of a sks dog in a bucket' trainer: devices: 1 num_nodes: 1 accelerator: gpu - precision: 16 + precision: bf16 logger: False # logger provided by exp_manager model: diff --git a/examples/multimodal/text_to_image/dreambooth/conf/dreambooth_lora_infer.yaml b/examples/multimodal/text_to_image/dreambooth/conf/dreambooth_lora_infer.yaml new file mode 100644 index 000000000000..b2af365e4d05 --- /dev/null +++ b/examples/multimodal/text_to_image/dreambooth/conf/dreambooth_lora_infer.yaml @@ -0,0 +1,33 @@ +name: stable-diffusion-train + +infer: + unconditional_guidance_scale: 7.5 + num_images_per_prompt: 4 + height: 512 + width: 512 + down_factor: 8 + inference_steps: 50 + sampler_type: 'DDIM' + eta: 0 + output_type: 'pil' + save_to_file: True + out_path: 'dreambooth' + seed: 123 + prompts: + - 'a photo of a sks dog' + - 'a photo of sks dog in a bucket' + + +trainer: + devices: 1 + num_nodes: 1 + accelerator: gpu + precision: 16 + logger: False # logger provided by exp_manager + +model: + precision: ${trainer.precision} + peft: + restore_from_path: null + unet_config: + from_pretrained: null # In case user want to load lora weights to a different unet ckpt than that is used in training \ No newline at end of file diff --git a/examples/multimodal/text_to_image/dreambooth/conf/dreambooth_lora_train.yaml b/examples/multimodal/text_to_image/dreambooth/conf/dreambooth_lora_train.yaml new file mode 100644 index 000000000000..283fbda56e33 --- /dev/null +++ b/examples/multimodal/text_to_image/dreambooth/conf/dreambooth_lora_train.yaml @@ -0,0 +1,241 @@ +name: Dreambooth-lora + +trainer: + devices: 1 + num_nodes: 1 + accelerator: gpu + precision: bf16-mixed + logger: False # logger provided by exp_manager + enable_checkpointing: False + use_distributed_sampler: False + max_epochs: -1 # PTL default. In practice, max_steps will be reached first. + max_steps: 500 # consumed_samples = global_step * micro_batch_size * data_parallel_size * accumulate_grad_batches + log_every_n_steps: 10 + accumulate_grad_batches: 1 # do not modify, grad acc is automatic for training megatron models + gradient_clip_val: 1.0 + benchmark: False + enable_model_summary: True + limit_val_batches: 0 + +exp_manager: + exp_dir: null + name: ${name} + create_checkpoint_callback: True + create_tensorboard_logger: True + checkpoint_callback_params: + every_n_train_steps: 200 + every_n_epochs: 0 + monitor: reduced_train_loss + save_on_train_epoch_end: False + filename: '${name}-{step}' + save_top_k: -1 + resume_if_exists: True + resume_ignore_no_checkpoint: True + resume_from_checkpoint: ${model.resume_from_checkpoint} + ema: + enable: False + decay: 0.9999 + validate_original_weights: False + every_n_steps: 1 + cpu_offload: False + + + +model: + precision: ${trainer.precision} + # specify micro_batch_size, global_batch_size, and model parallelism + # gradient accumulation will be done automatically based on data_parallel_size + micro_batch_size: 1 # limited by GPU memory + global_batch_size: 1 # will use more micro batches to reach global batch size + + with_prior_preservation: False + use_cached_latents: False + prior_loss_weight: 0.5 + train_text_encoder: False + restore_from_path: /ckpts/nemo-v1-5-188000-ema.nemo #This ckpt is only used to generate regularization images, thus .nemo ckpt is needed + + + + + linear_start: 0.00085 + linear_end: 0.012 + num_timesteps_cond: 1 + log_every_t: 200 + timesteps: 1000 + first_stage_key: images + cond_stage_key: captions + image_size: 64 + channels: 4 + cond_stage_trainable: false + conditioning_key: crossattn # check + monitor: val/loss_simple_ema + scale_factor: 0.18215 + use_ema: False + scale_by_std: False + ckpt_path: + ignore_keys: [ ] + parameterization: eps + clip_denoised: True + load_only_unet: False + cosine_s: 8e-3 + given_betas: + original_elbo_weight: 0 + v_posterior: 0 + l_simple_weight: 1 + use_positional_encodings: False + learn_logvar: False + logvar_init: 0 + beta_schedule: linear + loss_type: l2 + + concat_mode: True + cond_stage_forward: + text_embedding_dropout_rate: 0.1 + fused_opt: True + inductor: False + inductor_cudagraphs: False + channels_last: False + + unet_config: + _target_: nemo.collections.multimodal.modules.stable_diffusion.diffusionmodules.openaimodel.UNetModel + from_pretrained: /ckpts/unet.bin #load unet weights for finetuning, can use .ckpt ckpts from various sources + from_NeMo: False #Must be specified when from pretrained is not None, False means loading unet from HF ckpt + image_size: 32 # unused + in_channels: 4 + out_channels: 4 + model_channels: 320 + attention_resolutions: + - 4 + - 2 + - 1 + num_res_blocks: 2 + channel_mult: + - 1 + - 2 + - 4 + - 4 + num_heads: 8 + use_spatial_transformer: true + transformer_depth: 1 + context_dim: 768 + use_checkpoint: False + legacy: False + use_flash_attention: False + lora_network_alpha: null + + first_stage_config: + _target_: nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.autoencoder.AutoencoderKL + from_pretrained: /ckpts/vae.bin + #ckpt_path: /ckpts/vae.ckpt #to support original opensource weights files, please use ckpt_path to load it. + embed_dim: 4 + monitor: val/rec_loss + ddconfig: + double_z: true + z_channels: 4 + resolution: 256 #Never used + in_channels: 3 + out_ch: 3 + ch: 128 + ch_mult: + - 1 + - 2 + - 4 + - 4 + num_res_blocks: 2 + attn_resolutions: [ ] + dropout: 0.0 + lossconfig: + target: torch.nn.Identity + + cond_stage_config: + _target_: nemo.collections.multimodal.modules.stable_diffusion.encoders.modules.FrozenMegatronCLIPEmbedder + restore_from_path: /ckpts/openai.nemo + device: cuda + freeze: True + layer: "last" + enable_lora_finetune: False #to enable text encoder lora finetune, please enable both this one and "train_text_encoder" + # For compatibility of history version that uses HF clip model + # _target_: nemo.collections.multimodal.modules.stable_diffusion.encoders.modules.FrozenCLIPEmbedder + # version: openai/clip-vit-large-patch14 + # device: cuda + # max_length: 77 + # enable_lora_finetune: False #to enable text encoder lora finetune, please enable both this one and "train_text_encoder" + + noise_scheduler: + _target_: nemo.collections.multimodal.models.text_to_image.dreambooth.util.sd_noise_scheduler + parameterization: eps + v_posterior: 0 + given_betas: + beta_schedule: linear + timesteps: 1000 + linear_start: 0.00085 + linear_end: 0.012 + cosine_s: 8e-3 + + # miscellaneous + seed: 1234 + resume_from_checkpoint: null # manually set the checkpoint file to load from + apex_transformer_log_level: 30 # Python logging level displays logs with severity greater than or equal to this + gradient_as_bucket_view: True # PyTorch DDP argument. Allocate gradients in a contiguous bucket to save memory (less fragmentation and buffer memory) + + optim: + name: fused_adam + lr: 1e-4 + weight_decay: 0. + betas: + - 0.9 + - 0.999 + sched: + name: WarmupHoldPolicy + warmup_steps: 1 + hold_steps: 10000000000000 # Incredibly large value to hold the lr as constant + + # Nsys profiling options + nsys_profile: + enabled: False + start_step: 10 # Global batch to start profiling + end_step: 10 # Global batch to end profiling + ranks: [ 0 ] # Global rank IDs to profile + gen_shape: False # Generate model and kernel details including input shapes + + data: + name: pbss + num_workers: 4 + instance_dir: /home/scratch.zhuoyaow_gpu/workspace/SD_NeMo_EA/launcher_scripts/data/inst_dir + instance_prompt: a photo of a sks dog + regularization_dir: /home/scratch.zhuoyaow_gpu/workspace/SD_NeMo_EA/launcher_scripts/data/nemo_dogs + regularization_prompt: a photo of a dog + num_reg_images: 10 + num_images_per_prompt: 4 + resolution: 512 + center_crop: True + cached_instance_dir: #/datasets/instance_dir_cached + cached_reg_dir: #/datasets/nemo_dogs_cached + + peft: + peft_scheme: "sdlora" + restore_from_path: null + lora_tuning: + adapter_dim: 32 + network_alpha: 16 + adapter_dropout: 0.0 + column_init_method: 'xavier' # IGNORED if linear_adapter is used, options: xavier, zero or normal + row_init_method: 'zero' # IGNORED if linear_adapter is used, options: xavier, zero or normal + layer_selection: null # selects in which layers to add lora adapters. e.g. [1,12] will add lora to layer 1 (lowest) and 12. null will apply adapters to all layers + weight_tying: False + position_embedding_strategy: null # used only when weight_tying is True + +##The below infer config is to use inference script generating regularization images +infer: + unconditional_guidance_scale: 7.5 + num_images_per_prompt: ${model.data.num_images_per_prompt} + height: 512 + width: 512 + down_factor: 8 + inference_steps: 50 + sampler_type: 'PLMS' + eta: 0 + output_type: 'pil' + save_to_file: False + out_path: ${model.data.regularization_dir} + prompts: ${model.data.regularization_prompt} \ No newline at end of file diff --git a/examples/multimodal/text_to_image/dreambooth/dreambooth.py b/examples/multimodal/text_to_image/dreambooth/dreambooth.py index e8e7d776f1ff..70231e571331 100644 --- a/examples/multimodal/text_to_image/dreambooth/dreambooth.py +++ b/examples/multimodal/text_to_image/dreambooth/dreambooth.py @@ -21,6 +21,8 @@ from nemo.collections.multimodal.parts.stable_diffusion.pipeline import pipeline from nemo.collections.multimodal.parts.utils import setup_trainer_and_model_for_inference from nemo.collections.nlp.parts.megatron_trainer_builder import MegatronTrainerBuilder + +from nemo.collections.nlp.parts.peft_config import PEFT_CONFIG_MAP from nemo.core.config import hydra_runner from nemo.utils import logging from nemo.utils.exp_manager import exp_manager @@ -53,7 +55,9 @@ def model_cfg_modifier(model_cfg): model_cfg.global_batch_size = cfg.model.global_batch_size model_cfg.unet_config.from_pretrained = None model_cfg.first_stage_config.from_pretrained = None - model_cfg.target = 'nemo.collections.multimodal.models.stable_diffusion.ldm.ddpm.MegatronLatentDiffusion' + model_cfg.target = ( + 'nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.ddpm.MegatronLatentDiffusion' + ) trainer, megatron_diffusion_model = setup_trainer_and_model_for_inference( model_provider=MegatronLatentDiffusion, cfg=cfg, model_cfg_modifier=model_cfg_modifier @@ -101,6 +105,21 @@ def main(cfg): model = MegatronDreamBooth(cfg.model, trainer) + if cfg.model.get('peft', None): + + peft_cfg_cls = PEFT_CONFIG_MAP[cfg.model.peft.peft_scheme] + + if cfg.model.peft.restore_from_path is not None: + # initialize peft weights from a checkpoint instead of randomly + # This is not the same as resume training because optimizer states are not restored. + logging.info("PEFT Weights will be loaded from", cfg.model.peft.restore_from_path) + model.load_adapters(cfg.model.peft.restore_from_path, peft_cfg_cls(model_cfg)) + elif peft_cfg_cls is not None: + logging.info("Adding adapter weights to the model for PEFT") + model.add_adapter(peft_cfg_cls(cfg.model)) + else: + logging.info(f"Running full finetuning since no peft scheme is given.\n{model.summarize()}") + trainer.fit(model) diff --git a/examples/multimodal/text_to_image/dreambooth/dreambooth_infer.py b/examples/multimodal/text_to_image/dreambooth/dreambooth_infer.py index 672431d7b3fa..17952cea3b6b 100644 --- a/examples/multimodal/text_to_image/dreambooth/dreambooth_infer.py +++ b/examples/multimodal/text_to_image/dreambooth/dreambooth_infer.py @@ -28,7 +28,9 @@ def model_cfg_modifier(model_cfg): model_cfg.unet_config.use_flash_attention = False model_cfg.unet_config.from_pretrained = None model_cfg.first_stage_config.from_pretrained = None - model_cfg.target = 'nemo.collections.multimodal.models.stable_diffusion.ldm.ddpm.MegatronLatentDiffusion' + model_cfg.target = ( + 'nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.ddpm.MegatronLatentDiffusion' + ) trainer, megatron_diffusion_model = setup_trainer_and_model_for_inference( model_provider=MegatronLatentDiffusion, cfg=cfg, model_cfg_modifier=model_cfg_modifier diff --git a/examples/multimodal/text_to_image/dreambooth/dreambooth_lora_infer.py b/examples/multimodal/text_to_image/dreambooth/dreambooth_lora_infer.py new file mode 100644 index 000000000000..52f0aa2940d2 --- /dev/null +++ b/examples/multimodal/text_to_image/dreambooth/dreambooth_lora_infer.py @@ -0,0 +1,67 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. 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 +from omegaconf import open_dict +from pytorch_lightning import Trainer +from pytorch_lightning.plugins.environments import TorchElasticEnvironment + +from nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.ddpm import MegatronLatentDiffusion +from nemo.collections.multimodal.parts.stable_diffusion.pipeline import pipeline +from nemo.collections.multimodal.parts.utils import setup_trainer_and_model_for_inference +from nemo.collections.nlp.parts.nlp_overrides import NLPDDPStrategy, NLPSaveRestoreConnector +from nemo.collections.nlp.parts.peft_config import PEFT_CONFIG_MAP +from nemo.core.config import hydra_runner + + +@hydra_runner(config_path='conf', config_name='dreambooth_lora_infer') +def main(cfg): + def model_cfg_modifier(model_cfg): + model_cfg.precision = cfg.trainer.precision + model_cfg.ckpt_path = None + model_cfg.inductor = False + model_cfg.target = ( + 'nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.ddpm.MegatronLatentDiffusion' + ) + if cfg.model.unet_config.from_pretrained: + model_cfg.unet_config.from_pretrained = cfg.model.unet_config.from_pretrained + + model_cfg = MegatronLatentDiffusion.restore_from( + restore_path=cfg.model.peft.restore_from_path, + trainer=None, + save_restore_connector=NLPSaveRestoreConnector(), + return_config=True, + ) + + with open_dict(model_cfg): + model_cfg_modifier(model_cfg) + + plugins = [] + plugins.append(TorchElasticEnvironment()) + strategy = NLPDDPStrategy(no_ddp_communication_hook=True, find_unused_parameters=False,) + trainer = Trainer(plugins=plugins, strategy=strategy, **cfg.trainer) + + model = MegatronLatentDiffusion(model_cfg, trainer=trainer) + model.setup_complete = True + + peft_cfg_cls = PEFT_CONFIG_MAP[model_cfg.peft.peft_scheme] + + model.load_adapters(cfg.model.peft.restore_from_path, peft_cfg_cls(model_cfg)) + rng = torch.Generator().manual_seed(cfg.infer.seed) + + model = model.model.cuda().eval() + pipeline(model, cfg, rng=rng) + + +if __name__ == "__main__": + main() diff --git a/examples/multimodal/text_to_image/instruct_pix2pix/conf/sd_finetune.yaml b/examples/multimodal/text_to_image/instruct_pix2pix/conf/sd_finetune.yaml index 34ef1f436cd6..1c15b6e1a5fc 100644 --- a/examples/multimodal/text_to_image/instruct_pix2pix/conf/sd_finetune.yaml +++ b/examples/multimodal/text_to_image/instruct_pix2pix/conf/sd_finetune.yaml @@ -113,7 +113,7 @@ model: use_flash_attention: False first_stage_config: - _target_: nemo.collections.multimodal.models.stable_diffusion.ldm.autoencoder.AutoencoderKL + _target_: nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.autoencoder.AutoencoderKL from_pretrained: embed_dim: 4 monitor: val/rec_loss diff --git a/examples/multimodal/text_to_image/stable_diffusion/conf/sd2_train.yaml b/examples/multimodal/text_to_image/stable_diffusion/conf/sd2_train.yaml index 3cfc822f8462..b725b15f1ab2 100644 --- a/examples/multimodal/text_to_image/stable_diffusion/conf/sd2_train.yaml +++ b/examples/multimodal/text_to_image/stable_diffusion/conf/sd2_train.yaml @@ -119,7 +119,7 @@ model: use_flash_attention: False first_stage_config: - _target_: nemo.collections.multimodal.models.stable_diffusion.ldm.autoencoder.AutoencoderKL + _target_: nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.autoencoder.AutoencoderKL from_pretrained: embed_dim: 4 monitor: val/rec_loss diff --git a/examples/multimodal/text_to_image/stable_diffusion/conf/sd_fid_images.yaml b/examples/multimodal/text_to_image/stable_diffusion/conf/sd_fid_images.yaml index e526bc52d673..23a64a9607e3 100644 --- a/examples/multimodal/text_to_image/stable_diffusion/conf/sd_fid_images.yaml +++ b/examples/multimodal/text_to_image/stable_diffusion/conf/sd_fid_images.yaml @@ -32,6 +32,7 @@ infer: out_path: ${fid.save_path} seed: 123 prompts: + batch_size: 8 trainer: devices: ${fid.ntasks_per_node} @@ -42,4 +43,4 @@ trainer: model: restore_from_path: null - precision: ${trainer.precision} \ No newline at end of file + precision: ${trainer.precision} diff --git a/examples/multimodal/text_to_image/stable_diffusion/conf/sd_infer.yaml b/examples/multimodal/text_to_image/stable_diffusion/conf/sd_infer.yaml index dbe384dd2566..5a349387a0b4 100644 --- a/examples/multimodal/text_to_image/stable_diffusion/conf/sd_infer.yaml +++ b/examples/multimodal/text_to_image/stable_diffusion/conf/sd_infer.yaml @@ -3,6 +3,7 @@ name: stable-diffusion-train infer: unconditional_guidance_scale: 7.5 num_images_per_prompt: 4 + batch_size: 8 height: 512 width: 512 down_factor: 8 @@ -28,4 +29,4 @@ trainer: model: restore_from_path: null - precision: ${trainer.precision} \ No newline at end of file + precision: ${trainer.precision} diff --git a/examples/multimodal/text_to_image/stable_diffusion/conf/sd_lora_infer.yaml b/examples/multimodal/text_to_image/stable_diffusion/conf/sd_lora_infer.yaml new file mode 100644 index 000000000000..d77c24de704a --- /dev/null +++ b/examples/multimodal/text_to_image/stable_diffusion/conf/sd_lora_infer.yaml @@ -0,0 +1,34 @@ +name: stable-diffusion-train + +infer: + unconditional_guidance_scale: 7.5 + num_images_per_prompt: 4 + height: 512 + width: 512 + down_factor: 8 + inference_steps: 25 + sampler_type: 'DPM' + eta: 0 + output_type: 'pil' + save_to_file: True + out_path: 'stable-diffusion' + seed: 123 + prompts: + - 'A photo of a Shiba Inu dog with a backpack riding a bike. It is wearing sunglasses and a beach hat.' + - 'A cute corgi lives in a house made out of sushi.' + - 'A high contrast portrait of a very happy fuzzy panda dressed as a chef in a high end kitchen making dough. There is a painting of flowers on the wall behind him.' + - 'A brain riding a rocketship heading towards the moon.' + +trainer: + devices: 1 + num_nodes: 1 + accelerator: gpu + precision: 16 + logger: False # logger provided by exp_manager + +model: + precision: ${trainer.precision} + peft: + restore_from_path: null + unet_config: + from_pretrained: null # In case user want to load lora weights to a different unet ckpt than that is used in training \ No newline at end of file diff --git a/examples/multimodal/text_to_image/stable_diffusion/conf/sd_lora_train.yaml b/examples/multimodal/text_to_image/stable_diffusion/conf/sd_lora_train.yaml new file mode 100644 index 000000000000..3fbe03aaeaa1 --- /dev/null +++ b/examples/multimodal/text_to_image/stable_diffusion/conf/sd_lora_train.yaml @@ -0,0 +1,217 @@ +name: stable-diffusion-lora-train + +trainer: + devices: 1 + num_nodes: 1 + accelerator: gpu + precision: 16 + logger: False # logger provided by exp_manager + enable_checkpointing: False + use_distributed_sampler: False + max_epochs: 2 # PTL default. In practice, max_steps will be reached first. + max_steps: -1 # consumed_samples = global_step * micro_batch_size * data_parallel_size * accumulate_grad_batches + log_every_n_steps: 10 + accumulate_grad_batches: 1 # do not modify, grad acc is automatic for training megatron models + gradient_clip_val: 1.0 + benchmark: False + enable_model_summary: True + limit_val_batches: 0 + + +exp_manager: + exp_dir: null + name: ${name} + create_wandb_logger: False + wandb_logger_kwargs: + project: stable-diffusion + group: nemo-sd + name: ${name} + resume: True + create_checkpoint_callback: True + create_tensorboard_logger: True + checkpoint_callback_params: + every_n_train_steps: 1000 + every_n_epochs: 0 + monitor: reduced_train_loss + filename: '${name}--{reduced_train_loss:.2f}-{step}-{consumed_samples}' + resume_if_exists: True + resume_ignore_no_checkpoint: True + resume_from_checkpoint: ${model.resume_from_checkpoint} + ema: + enable: True + decay: 0.9999 + validate_original_weights: False + every_n_steps: 1 + cpu_offload: False + + +model: + precision: ${trainer.precision} + # specify micro_batch_size, global_batch_size, and model parallelism + # gradient accumulation will be done automatically based on data_parallel_size + micro_batch_size: 1 # limited by GPU memory + global_batch_size: 1 # will use more micro batches to reach global batch size + native_amp_init_scale: 65536.0 # Init scale for grad scaler used at fp16 + + + linear_start: 0.00085 + linear_end: 0.012 + num_timesteps_cond: 1 + log_every_t: 200 + timesteps: 1000 + first_stage_key: images + cond_stage_key: captions # txt for cifar, caption for pbss + image_size: 64 + channels: 4 + cond_stage_trainable: false + conditioning_key: crossattn # check + monitor: val/loss_simple_ema + scale_factor: 0.18215 + use_ema: False + scale_by_std: False + ckpt_path: + ignore_keys: [] + parameterization: eps + clip_denoised: True + load_only_unet: False + cosine_s: 8e-3 + given_betas: + original_elbo_weight: 0 + v_posterior: 0 + l_simple_weight: 1 + use_positional_encodings: False + learn_logvar: False + logvar_init: 0 + beta_schedule: linear + loss_type: l2 + + concat_mode: True + cond_stage_forward: + text_embedding_dropout_rate: 0.1 + fused_opt: True + inductor: False + inductor_cudagraphs: False + capture_cudagraph_iters: -1 # -1 to disable + channels_last: True + + unet_config: + _target_: nemo.collections.multimodal.modules.stable_diffusion.diffusionmodules.openaimodel.UNetModel + from_pretrained: /ckpts/nemo-v1-2.ckpt + from_NeMo: True #Must be specified when from pretrained is not None, False means loading unet from HF ckpt + image_size: 32 # unused + in_channels: 4 + out_channels: 4 + model_channels: 320 + attention_resolutions: + - 4 + - 2 + - 1 + num_res_blocks: 2 + channel_mult: + - 1 + - 2 + - 4 + - 4 + num_heads: 8 + use_spatial_transformer: true + transformer_depth: 1 + context_dim: 768 + use_checkpoint: False + legacy: False + use_flash_attention: True + enable_amp_o2_fp16: False + resblock_gn_groups: 32 + lora_network_alpha: null + + first_stage_config: + _target_: nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.autoencoder.AutoencoderKL + from_pretrained: /ckpts/vae.bin + embed_dim: 4 + monitor: val/rec_loss + ddconfig: + double_z: true + z_channels: 4 + resolution: 256 #Never used + in_channels: 3 + out_ch: 3 + ch: 128 + ch_mult: + - 1 + - 2 + - 4 + - 4 + num_res_blocks: 2 + attn_resolutions: [] + dropout: 0.0 + lossconfig: + target: torch.nn.Identity + + cond_stage_config: + _target_: nemo.collections.multimodal.modules.stable_diffusion.encoders.modules.FrozenMegatronCLIPEmbedder + restore_from_path: /ckpts/openai.nemo + device: cuda + freeze: True + layer: "last" + # For compatibility of history version that uses HF clip model + # _target_: nemo.collections.multimodal.modules.stable_diffusion.encoders.modules.FrozenCLIPEmbedder + # version: openai/clip-vit-large-patch14 + # device: cuda + # max_length: 77 + # capture_cudagraph_iters: ${model.capture_cudagraph_iters} + + + # miscellaneous + seed: 1234 + resume_from_checkpoint: null # manually set the checkpoint file to load from + apex_transformer_log_level: 30 # Python logging level displays logs with severity greater than or equal to this + gradient_as_bucket_view: True # PyTorch DDP argument. Allocate gradients in a contiguous bucket to save memory (less fragmentation and buffer memory) + ddp_overlap: True # True for using PyTorch DDP overlap. + + optim: + name: fused_adam + lr: 1e-4 + weight_decay: 0. + betas: + - 0.9 + - 0.999 + sched: + name: WarmupHoldPolicy + warmup_steps: 1 + hold_steps: 10000000000000 # Incredibly large value to hold the lr as constant + + # Nsys profiling options + nsys_profile: + enabled: False + start_step: 10 # Global batch to start profiling + end_step: 10 # Global batch to end profiling + ranks: [ 0 ] # Global rank IDs to profile + gen_shape: False # Generate model and kernel details including input shapes + + data: + num_workers: 16 + synthetic_data: False # dataset_path and local_root_path can be empty when using synthetic data + synthetic_data_length: 10000 + train: + dataset_path: + - /datasets/coyo/test.pkl + augmentations: + resize_smallest_side: 512 + center_crop_h_w: 512, 512 + horizontal_flip: False + filterings: + + webdataset: + infinite_sampler: False + local_root_path: /datasets/coyo + + peft: + peft_scheme: "sdlora" + restore_from_path: null + lora_tuning: + adapter_dim: 32 + adapter_dropout: 0.0 + column_init_method: 'xavier' # IGNORED if linear_adapter is used, options: xavier, zero or normal + row_init_method: 'zero' # IGNORED if linear_adapter is used, options: xavier, zero or normal + layer_selection: null # selects in which layers to add lora adapters. e.g. [1,12] will add lora to layer 1 (lowest) and 12. null will apply adapters to all layers + weight_tying: False + position_embedding_strategy: null # used only when weight_tying is True \ No newline at end of file diff --git a/examples/multimodal/text_to_image/stable_diffusion/conf/sd_train.yaml b/examples/multimodal/text_to_image/stable_diffusion/conf/sd_train.yaml index e87a99344d70..db1c138f9d3e 100644 --- a/examples/multimodal/text_to_image/stable_diffusion/conf/sd_train.yaml +++ b/examples/multimodal/text_to_image/stable_diffusion/conf/sd_train.yaml @@ -144,7 +144,6 @@ model: dropout: 0.0 lossconfig: target: torch.nn.Identity - capture_cudagraph_iters: ${model.capture_cudagraph_iters} cond_stage_config: _target_: nemo.collections.multimodal.modules.stable_diffusion.encoders.modules.FrozenMegatronCLIPEmbedder @@ -157,7 +156,6 @@ model: # version: openai/clip-vit-large-patch14 # device: cuda # max_length: 77 - # capture_cudagraph_iters: ${model.capture_cudagraph_iters} # miscellaneous @@ -193,7 +191,7 @@ model: synthetic_data_length: 10000 train: dataset_path: - - /datasets/coyo/wdinfo.pkl + - /datasets/coyo/test.pkl augmentations: resize_smallest_side: 512 center_crop_h_w: 512, 512 diff --git a/examples/multimodal/text_to_image/stable_diffusion/generate_fid_images.py b/examples/multimodal/text_to_image/stable_diffusion/generate_fid_images.py index d04a1d2b18af..27ea5913cbff 100644 --- a/examples/multimodal/text_to_image/stable_diffusion/generate_fid_images.py +++ b/examples/multimodal/text_to_image/stable_diffusion/generate_fid_images.py @@ -74,7 +74,7 @@ def model_cfg_modifier(model_cfg): model_cfg.unet_config.use_flash_attention = False model_cfg.unet_config.from_pretrained = None model_cfg.first_stage_config.from_pretrained = None - model_cfg.global_batch_size = model_cfg.micro_batch_size * ntasks_per_node + model_cfg.global_batch_size = cfg.infer.batch_size * ntasks_per_node # Set up the trainer and model for inference trainer, megatron_diffusion_model = setup_trainer_and_model_for_inference( @@ -84,13 +84,12 @@ def model_cfg_modifier(model_cfg): model.cuda().eval() # Generate images using the model and save them - for i, prompt in enumerate(input): - cfg.infer.prompts = [prompt] - rng = torch.Generator().manual_seed(cfg.infer.seed + local_task_id * 10 + node_id_per_cfg * 100 + i * 1000) - output = pipeline(model, cfg, rng=rng) - for image in output[0]: - image_num = i + partition_size_per_node * node_id_per_cfg + partition_size_per_task * local_task_id - image.save(os.path.join(save_path, f'image{image_num:06d}.png')) + cfg.infer.prompts = input + rng = torch.Generator().manual_seed(cfg.infer.seed + local_task_id * 10 + node_id_per_cfg * 100) + output = pipeline(model, cfg, rng=rng) + for i, image in enumerate(img for batch in output for img in batch): + image_num = i + partition_size_per_node * node_id_per_cfg + partition_size_per_task * local_task_id + image.save(os.path.join(save_path, f'image{image_num:06d}.png')) if __name__ == "__main__": diff --git a/examples/multimodal/text_to_image/stable_diffusion/sd_lora_infer.py b/examples/multimodal/text_to_image/stable_diffusion/sd_lora_infer.py new file mode 100644 index 000000000000..0877d4eb4b2f --- /dev/null +++ b/examples/multimodal/text_to_image/stable_diffusion/sd_lora_infer.py @@ -0,0 +1,64 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. 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 +from omegaconf import open_dict +from pytorch_lightning import Trainer +from pytorch_lightning.plugins.environments import TorchElasticEnvironment + +from nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.ddpm import MegatronLatentDiffusion +from nemo.collections.multimodal.parts.stable_diffusion.pipeline import pipeline +from nemo.collections.multimodal.parts.utils import setup_trainer_and_model_for_inference +from nemo.collections.nlp.parts.nlp_overrides import NLPDDPStrategy, NLPSaveRestoreConnector +from nemo.collections.nlp.parts.peft_config import PEFT_CONFIG_MAP +from nemo.core.config import hydra_runner + + +@hydra_runner(config_path='conf', config_name='dreambooth_lora_infer') +def main(cfg): + def model_cfg_modifier(model_cfg): + model_cfg.precision = cfg.trainer.precision + model_cfg.ckpt_path = None + model_cfg.inductor = False + if cfg.model.unet_config.from_pretrained: + model_cfg.unet_config.from_pretrained = cfg.model.unet_config.from_pretrained + + model_cfg = MegatronLatentDiffusion.restore_from( + restore_path=cfg.model.peft.restore_from_path, + trainer=None, + save_restore_connector=NLPSaveRestoreConnector(), + return_config=True, + ) + + with open_dict(model_cfg): + model_cfg_modifier(model_cfg) + + plugins = [] + plugins.append(TorchElasticEnvironment()) + strategy = NLPDDPStrategy(no_ddp_communication_hook=True, find_unused_parameters=False,) + trainer = Trainer(plugins=plugins, strategy=strategy, **cfg.trainer) + + model = MegatronLatentDiffusion(model_cfg, trainer=trainer) + model.setup_complete = True + + peft_cfg_cls = PEFT_CONFIG_MAP[model_cfg.peft.peft_scheme] + + model.load_adapters(cfg.model.peft.restore_from_path, peft_cfg_cls(model_cfg)) + rng = torch.Generator().manual_seed(cfg.infer.seed) + + model = model.model.cuda().eval() + pipeline(model, cfg, rng=rng) + + +if __name__ == "__main__": + main() diff --git a/examples/multimodal/text_to_image/stable_diffusion/sd_train.py b/examples/multimodal/text_to_image/stable_diffusion/sd_train.py index 9259b4960734..434150516d0c 100644 --- a/examples/multimodal/text_to_image/stable_diffusion/sd_train.py +++ b/examples/multimodal/text_to_image/stable_diffusion/sd_train.py @@ -20,6 +20,7 @@ from nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.ddpm import MegatronLatentDiffusion from nemo.collections.nlp.parts.megatron_trainer_builder import MegatronTrainerBuilder from nemo.collections.nlp.parts.nlp_overrides import NLPDDPStrategy +from nemo.collections.nlp.parts.peft_config import PEFT_CONFIG_MAP from nemo.core.config import hydra_runner from nemo.utils import logging from nemo.utils.exp_manager import exp_manager @@ -55,29 +56,27 @@ def main(cfg) -> None: torch.backends.cuda.matmul.allow_tf32 = True - if cfg.model.capture_cudagraph_iters >= 0: - # Required by CUDA graph with DDP - os.environ["NCCL_ASYNC_ERROR_HANDLING"] = "0" - - # Hack to avoid CUDA graph issue with AMP, PyTorch Lightning doesn't support - # changing autocast arguments for now. - # https://github.com/pytorch/pytorch/blob/v1.13.1/torch/cuda/graphs.py#L234 - def amp_autocast_init(self, *args, **kwargs): - if "cache_enabled" not in kwargs: - kwargs["cache_enabled"] = False - return self.__orig_init__(*args, **kwargs) - - torch.cuda.amp.autocast.__orig_init__ = torch.cuda.amp.autocast.__init__ - torch.cuda.amp.autocast.__init__ = amp_autocast_init - torch.autocast.__orig_init__ = torch.autocast.__init__ - torch.autocast.__init__ = amp_autocast_init - trainer = MegatronStableDiffusionTrainerBuilder(cfg).create_trainer() exp_manager(trainer, cfg.exp_manager) model = MegatronLatentDiffusion(cfg.model, trainer) + if cfg.model.get('peft', None): + + peft_cfg_cls = PEFT_CONFIG_MAP[cfg.model.peft.peft_scheme] + + if cfg.model.peft.restore_from_path is not None: + # initialize peft weights from a checkpoint instead of randomly + # This is not the same as resume training because optimizer states are not restored. + logging.info("PEFT Weights will be loaded from", cfg.model.peft.restore_from_path) + model.load_adapters(cfg.model.peft.restore_from_path, peft_cfg_cls(model_cfg)) + elif peft_cfg_cls is not None: + logging.info("Adding adapter weights to the model for PEFT") + model.add_adapter(peft_cfg_cls(cfg.model)) + else: + logging.info(f"Running full finetuning since no peft scheme is given.\n{model.summarize()}") + trainer.fit(model) diff --git a/examples/multimodal/vision_language_foundation/clip/megatron_clip_infer.py b/examples/multimodal/vision_language_foundation/clip/megatron_clip_infer.py index d77802e5a010..c99e7cbfc3bc 100644 --- a/examples/multimodal/vision_language_foundation/clip/megatron_clip_infer.py +++ b/examples/multimodal/vision_language_foundation/clip/megatron_clip_infer.py @@ -46,11 +46,11 @@ def model_cfg_modifier(model_cfg): ) if model.cfg.get("megatron_amp_O2", False): - vision_encoder = model.model.module.vision_encoder - text_encoder = model.model.module.text_encoder + vision_encoder = model.model.module.vision_encoder.eval() + text_encoder = model.model.module.text_encoder.eval() else: - vision_encoder = model.model.vision_encoder - text_encoder = model.model.text_encoder + vision_encoder = model.model.vision_encoder.eval() + text_encoder = model.model.text_encoder.eval() val_image_transform, text_transform = get_preprocess_fns(model.cfg, model.tokenizer, is_train=False,) diff --git a/nemo/README.md b/nemo/README.md index d7c95a070979..91b734b64361 100644 --- a/nemo/README.md +++ b/nemo/README.md @@ -7,4 +7,5 @@ NeMo (**Ne**ural **Mo**dules) is a toolkit for creating AI applications built ar * ASR - collection of modules and models for building speech recognition networks * TTS - collection of modules and models for building speech synthesis networks * NLP - collection of modules and models for building NLP networks +* Vision - collection of modules and models for building computer vision networks * Multimodal - collection of modules and models for building multimodal networks diff --git a/nemo/collections/multimodal/data/clip/augmentations/augmentations.py b/nemo/collections/multimodal/data/clip/augmentations/augmentations.py index a0a96d39de04..d1de22f687e5 100644 --- a/nemo/collections/multimodal/data/clip/augmentations/augmentations.py +++ b/nemo/collections/multimodal/data/clip/augmentations/augmentations.py @@ -16,7 +16,8 @@ https://github.com/mlfoundations/open_clip/blob/28c994406e39a5babc749c76871d92f33e9c558d/src/open_clip/transform.py by @yaoyu-33 """ -from typing import Optional, Tuple +from dataclasses import asdict, dataclass +from typing import Any, Dict, Optional, Tuple, Union import torch import torch.nn as nn @@ -37,10 +38,23 @@ except (ImportError, ModuleNotFoundError): TORCHVISION_AVAILABLE = False +from nemo.utils import logging + OPENAI_DATASET_MEAN = (0.48145466, 0.4578275, 0.40821073) OPENAI_DATASET_STD = (0.26862954, 0.26130258, 0.27577711) +@dataclass +class AugmentationCfg: + scale: Tuple[float, float] = (0.9, 1.0) + ratio: Optional[Tuple[float, float]] = None + color_jitter: Optional[Union[float, Tuple[float, float, float]]] = None + interpolation: Optional[str] = None + re_prob: Optional[float] = None + re_count: Optional[int] = None + use_timm: bool = False + + class ResizeMaxSize(nn.Module): def __init__(self, max_size, interpolation=InterpolationMode.BICUBIC, fn='max', fill=0): super().__init__() @@ -78,6 +92,7 @@ def image_transform( std: Optional[Tuple[float, ...]] = None, resize_longest_max: bool = False, fill_color: int = 0, + aug_cfg: Optional[Union[Dict[str, Any], AugmentationCfg]] = None, ): assert TORCHVISION_AVAILABLE, "Torchvision imports failed but they are required." mean = mean or OPENAI_DATASET_MEAN @@ -92,16 +107,50 @@ def image_transform( # for square size, pass size as int so that Resize() uses aspect preserving shortest edge image_size = image_size[0] + if isinstance(aug_cfg, dict): + aug_cfg = AugmentationCfg(**aug_cfg) + else: + aug_cfg = aug_cfg or AugmentationCfg() normalize = Normalize(mean=mean, std=std) if is_train: - return Compose( - [ - RandomResizedCrop(image_size, scale=(0.9, 1.0), interpolation=InterpolationMode.BICUBIC), - _convert_to_rgb, - ToTensor(), - normalize, - ] - ) + aug_cfg_dict = {k: v for k, v in asdict(aug_cfg).items() if v is not None} + use_timm = aug_cfg_dict.pop('use_timm', False) + if use_timm: + from timm.data import create_transform # timm can still be optional + + if isinstance(image_size, (tuple, list)): + assert len(image_size) >= 2 + input_size = (3,) + image_size[-2:] + else: + input_size = (3, image_size, image_size) + # by default, timm aug randomly alternates bicubic & bilinear for better robustness at inference time + aug_cfg_dict.setdefault('interpolation', 'random') + aug_cfg_dict.setdefault('color_jitter', None) # disable by default + train_transform = create_transform( + input_size=input_size, + is_training=True, + hflip=0.0, + mean=mean, + std=std, + re_mode='pixel', + **aug_cfg_dict, + ) + else: + train_transform = Compose( + [ + RandomResizedCrop( + image_size, scale=aug_cfg_dict.pop('scale'), interpolation=InterpolationMode.BICUBIC, + ), + _convert_to_rgb, + ToTensor(), + normalize, + ] + ) + if aug_cfg_dict: + logging.warning( + f'Unused augmentation cfg items, specify `use_timm` to use ({list(aug_cfg_dict.keys())}).' + ) + return train_transform else: if resize_longest_max: transforms = [ResizeMaxSize(image_size, fill=fill_color)] diff --git a/nemo/collections/multimodal/data/common/utils.py b/nemo/collections/multimodal/data/common/utils.py new file mode 100644 index 000000000000..31e83feb1375 --- /dev/null +++ b/nemo/collections/multimodal/data/common/utils.py @@ -0,0 +1,33 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. 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 open_clip +import torch + + +def get_collate_fn(first_stage_key="images_moments", cond_stage_key="captions"): + def collate_fn_with_tokenize(batch): + images_moments = [s[first_stage_key] for s in batch] + cond_inputs = [s[cond_stage_key] for s in batch] + if cond_stage_key == "captions": + tokens = open_clip.tokenize(cond_inputs) + else: + tokens = torch.stack(cond_inputs) + batch = { + first_stage_key: torch.cat(images_moments), + cond_stage_key: tokens, + } + return batch + + return collate_fn_with_tokenize diff --git a/nemo/collections/multimodal/data/common/webdataset.py b/nemo/collections/multimodal/data/common/webdataset.py index d0e1b19d444e..8d70a03fa911 100644 --- a/nemo/collections/multimodal/data/common/webdataset.py +++ b/nemo/collections/multimodal/data/common/webdataset.py @@ -11,6 +11,7 @@ # 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 glob import io import itertools import json @@ -123,6 +124,13 @@ def __init__( self.augmentations = dataset_cfg.validation.get("augmentations", None) self.filterings = dataset_cfg.validation.get("filterings", None) + # Optionally expand dataset as as a glob pattern + # This can be used to specify multiple .zip files: dataset_path="data/*.zip" + if isinstance(dataset_path, str): + glob_path = dataset_path + dataset_path = glob.glob(dataset_path) + assert len(dataset_path) > 0, f"No files found for {glob_path}" + if "boto3" in dataset_cfg: logging.info(f'Init boto3 using credentials file at {dataset_cfg.boto3.credentials_file}') self.use_boto3 = True diff --git a/nemo/collections/multimodal/data/neva/conversation.py b/nemo/collections/multimodal/data/neva/conversation.py index 4e53eb5190f6..886049dd5170 100644 --- a/nemo/collections/multimodal/data/neva/conversation.py +++ b/nemo/collections/multimodal/data/neva/conversation.py @@ -15,6 +15,18 @@ from enum import Enum, auto from typing import List +DEFAULT_PAD_TOKEN = "" +DEFAULT_BOS_TOKEN = "" +DEFAULT_EOS_TOKEN = "" +DEFAULT_UNK_TOKEN = "" +DEFAULT_IMAGE_TOKEN = "" +DEFAULT_SYSTEM_TOKEN = "" +DEFAULT_SEPARATOR_TOKEN = "" +DEFAULT_LABELS_TOKEN = "" +DEFAULT_IMAGE_PATCH_TOKEN = "" +DEFAULT_IM_START_TOKEN = "" +DEFAULT_IM_END_TOKEN = "" + class SeparatorStyle(Enum): """Different separator style.""" @@ -70,6 +82,8 @@ def get_prompt(self): if type(message) is tuple: message, _, _ = message ret += role + ": " + message + seps[i % 2] + if i % 2 == 1 and i != len(messages) - 1: # Assistant end + ret += " " else: ret += role + ":" elif self.sep_style == SeparatorStyle.LLAMA_2: @@ -88,7 +102,7 @@ def get_prompt(self): message = wrap_sys(self.system) + message if i % 2 == 0: message = wrap_inst(message) - ret += self.sep + message + ret += self.sep + " " + message else: ret += " " + message + " " + self.sep2 else: @@ -245,8 +259,8 @@ def dict(self): messages=(), offset=0, sep_style=SeparatorStyle.NVGPT, - sep="", - sep2="System\n", + sep=DEFAULT_SEPARATOR_TOKEN, + sep2=f"{DEFAULT_SYSTEM_TOKEN}System\n", ) conv_vicuna_v0 = Conversation( @@ -291,7 +305,7 @@ def dict(self): offset=0, sep_style=SeparatorStyle.TWO, sep=" ", - sep2="", + sep2=DEFAULT_EOS_TOKEN, ) conv_llama_2 = Conversation( @@ -303,8 +317,8 @@ def dict(self): messages=(), offset=0, sep_style=SeparatorStyle.LLAMA_2, - sep="", - sep2="", + sep=DEFAULT_BOS_TOKEN, + sep2=DEFAULT_EOS_TOKEN, ) conv_llava_llama_2 = Conversation( @@ -316,8 +330,8 @@ def dict(self): messages=(), offset=0, sep_style=SeparatorStyle.LLAMA_2, - sep="", - sep2="", + sep=DEFAULT_BOS_TOKEN, + sep2=DEFAULT_EOS_TOKEN, ) conv_llava_plain = Conversation( @@ -355,7 +369,7 @@ def dict(self): offset=0, sep_style=SeparatorStyle.TWO, sep=" ", - sep2="", + sep2=DEFAULT_EOS_TOKEN, ) conv_llava_v1_mmtag = Conversation( @@ -367,7 +381,7 @@ def dict(self): offset=0, sep_style=SeparatorStyle.TWO, sep=" ", - sep2="", + sep2=DEFAULT_EOS_TOKEN, version="v1_mmtag", ) diff --git a/nemo/collections/multimodal/data/neva/neva_dataset.py b/nemo/collections/multimodal/data/neva/neva_dataset.py index 7ed1597814c1..4dd6b120c8c8 100644 --- a/nemo/collections/multimodal/data/neva/neva_dataset.py +++ b/nemo/collections/multimodal/data/neva/neva_dataset.py @@ -30,21 +30,24 @@ from transformers import CLIPImageProcessor import nemo.collections.multimodal.data.neva.conversation as conversation_lib +from nemo.collections.multimodal.data.clip.augmentations.augmentations import image_transform +from nemo.collections.multimodal.data.neva.conversation import ( + DEFAULT_BOS_TOKEN, + DEFAULT_EOS_TOKEN, + DEFAULT_IM_END_TOKEN, + DEFAULT_IM_START_TOKEN, + DEFAULT_IMAGE_PATCH_TOKEN, + DEFAULT_IMAGE_TOKEN, + DEFAULT_LABELS_TOKEN, + DEFAULT_PAD_TOKEN, + DEFAULT_SEPARATOR_TOKEN, + DEFAULT_SYSTEM_TOKEN, + DEFAULT_UNK_TOKEN, +) from nemo.collections.nlp.modules.common.megatron.utils import get_ltor_masks_and_position_ids -MAX_NUM_IMAGES = 4 +MAX_NUM_IMAGES = 1 IGNORE_INDEX = -1 -DEFAULT_PAD_TOKEN = "" -DEFAULT_BOS_TOKEN = "" -DEFAULT_EOS_TOKEN = "" -DEFAULT_UNK_TOKEN = "" -DEFAULT_IMAGE_TOKEN = "" -DEFAULT_SYSTEM_TOKEN = "" -DEFAULT_SEPARATOR_TOKEN = "" -DEFAULT_LABELS_TOKEN = "" -DEFAULT_IMAGE_PATCH_TOKEN = "" -DEFAULT_IM_START_TOKEN = "" -DEFAULT_IM_END_TOKEN = "" class TarOrFolderImageLoader: @@ -135,34 +138,36 @@ def tokenize( return result -def preprocess_multimodal(sources: dict, multimodal_cfg: dict, cur_token_len: int,) -> Dict: +def preprocess_multimodal(sources: dict, multimodal_cfg: dict, cur_token_len: int, use_plain: bool = False) -> Dict: """ - Preprocesses a given multimodal input based on specified configurations. + Preprocesses multimodal sources based on the provided configuration. - This function modifies the 'sources' dictionary, primarily focusing on conversations. It checks if the input - is multimodal based on 'multimodal_cfg'. If not, it returns the 'sources' unmodified. For multimodal inputs, - it processes each conversation in 'sources'. If 'sep_image_conv_front' is set in 'multimodal_cfg', the function - asserts the presence of 'DEFAULT_IMAGE_TOKEN' at the beginning of each conversation, removes it, and restructures - the conversation's first turn with this token and other formatting details. Furthermore, the function replaces - 'DEFAULT_IMAGE_TOKEN' with a series of 'DEFAULT_IMAGE_PATCH_TOKEN' tokens, the count of which depends on - 'image_token_len' and 'use_im_start_end' configuration. + This function modifies the sources for multimodal data processing. It checks if the data is multimodal and + adjusts the token lengths accordingly. It also handles the start and end tokens for images and replaces + image tokens in conversations. Parameters: - - sources (dict): A dictionary containing the source data to be processed. Each source is expected to have - 'conversations' as one of its keys. - - multimodal_cfg (dict): A configuration dictionary specifying how the multimodal data should be processed. - Key configurations include 'is_multimodal', 'sep_image_conv_front', and 'use_im_start_end'. - - cur_token_len (int): The current length of image tokens, used to determine the number of patch tokens - to replace the 'DEFAULT_IMAGE_TOKEN'. + - sources (dict): A dictionary containing the multimodal sources to be processed. + - multimodal_cfg (dict): A configuration dictionary specifying various options for multimodal processing. + It includes keys like 'is_multimodal', 'use_im_start_end', and 'sep_image_conv_front'. + - cur_token_len (int): The current length of tokens to be considered for image processing. + - use_plain (bool, optional): A boolean flag to use plain image token replacement without additional processing. + Defaults to False. Returns: - - dict: The modified 'sources' dictionary after applying the multimodal preprocessing. + - dict: The processed sources dictionary after applying multimodal preprocessing steps. """ is_multimodal = multimodal_cfg['is_multimodal'] image_token_len = cur_token_len if not is_multimodal: return sources + if multimodal_cfg['use_im_start_end']: + replace_token = DEFAULT_IMAGE_PATCH_TOKEN * image_token_len + else: + replace_token = DEFAULT_IMAGE_PATCH_TOKEN * (image_token_len - 2) + replace_token = DEFAULT_IM_START_TOKEN + replace_token + DEFAULT_IM_END_TOKEN + for source in sources: conversation = source['conversations'] if multimodal_cfg['sep_image_conv_front']: @@ -175,12 +180,10 @@ def preprocess_multimodal(sources: dict, multimodal_cfg: dict, cur_token_len: in + ": " + conversation[0]['value'] ) + if use_plain: + assert DEFAULT_IMAGE_TOKEN in conversation[0]['value'] + conversation[0]['value'] = DEFAULT_IMAGE_TOKEN for turn in conversation: - if multimodal_cfg['use_im_start_end']: - replace_token = DEFAULT_IMAGE_PATCH_TOKEN * image_token_len - else: - replace_token = DEFAULT_IMAGE_PATCH_TOKEN * (image_token_len - 2) - replace_token = DEFAULT_IM_START_TOKEN + replace_token + DEFAULT_IM_END_TOKEN turn["value"] = turn["value"].replace(DEFAULT_IMAGE_TOKEN, replace_token) return sources @@ -188,24 +191,19 @@ def preprocess_multimodal(sources: dict, multimodal_cfg: dict, cur_token_len: in def preprocess_llama_2(sources: dict, tokenizer, cfg,) -> Dict: """ - Preprocess a given set of conversational sources using llama_2 chat conversation template + Preprocesses sources for the LLaMA 2 model configuration. - This function processes conversations by first ensuring the conversation starts with a 'human' role, then tokenizes the conversations, applies specific token replacements, and finally masks labels for training purposes. + The function applies prompt templates and tokenizes the conversations according to the LLaMA 2 model specifications. + It involves special handling of tokens, masking of labels, and adjustments based on configuration settings. Parameters: - - sources: A dictionary containing conversational data. Expected format is a dict of conversations, where each conversation is a list of messages, and each message is a dict with 'from' (role) and 'value' (message text). - - tokenizer: A tokenizer from the Hugging Face Transformers library used for tokenizing the conversations. - - cfg: Configuration settings which include 'add_extra_token' (bool) to determine if an extra token should be added to the tokenized output, and 'context_length' for specifying the tokenization context length. + - sources (dict): A dictionary of sources containing conversations to be processed. + - tokenizer: The tokenizer to be used for processing the text. + - cfg: Configuration settings for preprocessing, including context length and additional tokens. Returns: - - Dict: A dictionary containing two keys: - - 'tokens': A tensor of tokenized conversation data. - - 'labels': A tensor of labels for the conversation data, used for training models. Labels are masked based on the conversation structure. - - Note: - - The function includes specific token replacements (e.g., DEFAULT_IMAGE_PATCH_TOKEN, , ) and masking techniques for labels. - - It is designed to work with conversational data where messages alternate between a 'human' and a 'gpt' role. - - The function asserts that each message in a conversation alternates between the defined roles and skips messages not starting with the 'human' role. + - Dict: A dictionary containing tokenized and labeled data suitable for the LLaMA 2 model. + This includes tokens, labels, and any special processing as defined in the configuration. """ conv = conversation_lib.conv_llava_llama_2.copy() roles = {"human": conv.roles[0], "gpt": conv.roles[1]} @@ -259,7 +257,7 @@ def preprocess_llama_2(sources: dict, tokenizer, cfg,) -> Dict: round_len = len(tokenizer.text_to_ids(rou + conv.sep2)) if i > 0: round_len -= 1 # Remove extra token added by sp tokenizer - instruction_len = len(tokenizer.text_to_ids(parts[0])) - 1 + instruction_len = len(tokenizer.text_to_ids(parts[0])) - 2 target[cur_len : cur_len + instruction_len] = IGNORE_INDEX cur_len += round_len @@ -280,24 +278,18 @@ def preprocess_llama_2(sources: dict, tokenizer, cfg,) -> Dict: def preprocess_v1(sources: dict, tokenizer, cfg,) -> Dict: """ - Preprocess a given set of conversational sources using vicuna v1 conversation template + Preprocesses sources for the Vicuna V1 model configuration. - This function processes conversations by first ensuring the conversation starts with a 'human' role, then tokenizes the conversations, applies specific token replacements, and finally masks labels for training purposes. + Similar to `preprocess_llama_2`, this function applies prompt templates and performs tokenization, but it is tailored + for the Vicuna V1 model. It includes specific handling for token translations, label masking, and tokenizer configuration. Parameters: - - sources: A dictionary containing conversational data. Expected format is a dict of conversations, where each conversation is a list of messages, and each message is a dict with 'from' (role) and 'value' (message text). - - tokenizer: A tokenizer from the Hugging Face Transformers library used for tokenizing the conversations. - - cfg: Configuration settings which include 'add_extra_token' (bool) to determine if an extra token should be added to the tokenized output, and 'context_length' for specifying the tokenization context length. + - sources (dict): A dictionary of sources containing conversations to be processed. + - tokenizer: The tokenizer to be used for processing the text. + - cfg: Configuration settings for preprocessing, which may include context length and additional tokens. Returns: - - Dict: A dictionary containing two keys: - - 'tokens': A tensor of tokenized conversation data. - - 'labels': A tensor of labels for the conversation data, used for training models. Labels are masked based on the conversation structure. - - Note: - - The function includes specific token replacements (e.g., DEFAULT_IMAGE_PATCH_TOKEN, , ) and masking techniques for labels. - - It is designed to work with conversational data where messages alternate between a 'human' and a 'gpt' role. - - The function asserts that each message in a conversation alternates between the defined roles and skips messages not starting with the 'human' role. + - Dict: A dictionary containing the processed data, including tokens and labels, formatted for the Vicuna V1 model. """ conv = conversation_lib.conv_vicuna_v1.copy() roles = {"human": conv.roles[0], "gpt": conv.roles[1]} @@ -400,8 +392,8 @@ def preprocess_nvgpt(sources: dict, tokenizer, cfg,) -> Dict: strip_end_for_inference = False for i, turn in enumerate(source['conversations']): - if i % 2 == 0: - turn['from'] = conv.roles[0] + if i % 2 == 1: + turn['from'] = conv.roles[1] if 'label' not in turn: turn[ 'label' @@ -413,7 +405,7 @@ def preprocess_nvgpt(sources: dict, tokenizer, cfg,) -> Dict: True # in inference, current turn is empty, thus end tokens need to striped. ) else: - turn['from'] = conv.roles[1] + turn['from'] = conv.roles[0] conv.append_message(turn['from'], turn['value']) context = conv.get_prompt() if strip_end_for_inference: @@ -470,6 +462,57 @@ def preprocess_nvgpt(sources: dict, tokenizer, cfg,) -> Dict: return dict(tokens=tokens, labels=labels,) +def preprocess_plain(sources, tokenizer, cfg,) -> Dict: + """ + Preprocesses plain text sources (no template) for tokenization and label generation. + + This function concatenates conversations with an end signal, tokenizes them, and prepares labels for training. + It handles sources with a specific structure (expecting two elements in 'conversations') and includes the + option to add an extra token as specified in the configuration. The function also applies masking to the labels. + + Parameters: + - sources: A list of source dictionaries. Each source dictionary should have a key 'conversations' + containing a list of conversation parts. + - tokenizer: The tokenizer to be used for converting text to tokens. + - cfg: Configuration dictionary which may include 'context_length' and 'add_extra_token' settings. + + Returns: + - Dict: A dictionary containing tokenized data and corresponding labels. This includes 'tokens' which are the + tokenized representations of the conversations, and 'labels' which are used for training the model. The labels + have specific indices masked with IGNORE_INDEX as per the preprocessing logic. + """ + # add end signal and concatenate together + conversations = [] + for source in sources: + source = source['conversations'] + assert len(source) == 2 + # This line is different from LLaVA repo, we inserted '\n' after . + conversation = source[0]['value'] + source[1]['value'] + '\n' + conversations.append(conversation) + # tokenize conversations + add_extra_token = cfg.get("add_extra_token") + tokens = tokenize( + texts=conversations, + tokenizer=tokenizer, + context_length=cfg.get("context_length"), + add_extra_token=add_extra_token, + ) + labels = tokens.clone().detach() + for target, source in zip(labels, sources): + source = source['conversations'] + tokenized_len = len(tokenizer.text_to_ids(source[0]['value'])) + target[:tokenized_len] = IGNORE_INDEX + + if add_extra_token: + tokens = tokens[:, :-1].contiguous() + labels = labels[:, 1:].contiguous() + else: + labels = torch.roll(labels, shifts=-1, dims=-1) + labels[:, -1] = IGNORE_INDEX + + return dict(tokens=tokens, labels=labels,) + + class LazySupervisedDataset(Dataset): """Dataset for supervised fine-tuning.""" @@ -498,7 +541,6 @@ def __len__(self): def __getitem__(self, i) -> Dict[str, torch.Tensor]: sources = self.list_data_dict[i] - processor = self.processor if isinstance(i, int): sources = [sources] assert len(sources) == 1, "Don't know why it is wrapped to a list" # FIXME @@ -511,33 +553,40 @@ def __getitem__(self, i) -> Dict[str, torch.Tensor]: image = self.image_loader.open_image(image_file) if image is None: logging.warning(f"Image {image_file} could not be found!") - if self.multimodal_cfg['image_aspect_ratio'] == 'keep': - max_hw, min_hw = max(image.size), min(image.size) - aspect_ratio = max_hw / min_hw - max_len, min_len = 448, 224 - shortest_edge = int(min(max_len / aspect_ratio, min_len)) - image = processor.preprocess( - image, return_tensors='pt', do_center_crop=False, size={"shortest_edge": shortest_edge} - )['pixel_values'][0] - elif self.multimodal_cfg['image_aspect_ratio'] == 'pad': - - def expand2square(pil_img, background_color): - width, height = pil_img.size - if width == height: - return pil_img - elif width > height: - result = Image.new(pil_img.mode, (width, width), background_color) - result.paste(pil_img, (0, (width - height) // 2)) - return result - else: - result = Image.new(pil_img.mode, (height, height), background_color) - result.paste(pil_img, ((height - width) // 2, 0)) - return result - - image = expand2square(image, tuple(int(x * 255) for x in processor.image_mean)) - image = processor.preprocess(image, return_tensors='pt')['pixel_values'][0] + if isinstance(self.processor, CLIPImageProcessor): + # image processor from HF + if self.multimodal_cfg['image_aspect_ratio'] == 'keep': + max_hw, min_hw = max(image.size), min(image.size) + aspect_ratio = max_hw / min_hw + max_len, min_len = 448, 224 + shortest_edge = int(min(max_len / aspect_ratio, min_len)) + image = self.processor.preprocess( + image, return_tensors='pt', do_center_crop=False, size={"shortest_edge": shortest_edge} + )['pixel_values'][0] + elif self.multimodal_cfg['image_aspect_ratio'] == 'pad': + + def expand2square(pil_img, background_color): + width, height = pil_img.size + if width == height: + return pil_img + elif width > height: + result = Image.new(pil_img.mode, (width, width), background_color) + result.paste(pil_img, (0, (width - height) // 2)) + return result + else: + result = Image.new(pil_img.mode, (height, height), background_color) + result.paste(pil_img, ((height - width) // 2, 0)) + return result + + image = expand2square(image, tuple(int(x * 255) for x in self.processor.image_mean)) + image = self.processor.preprocess(image, return_tensors='pt')['pixel_values'][0] + else: + image = self.processor.preprocess(image, return_tensors='pt')['pixel_values'][0] else: - image = processor.preprocess(image, return_tensors='pt')['pixel_values'][0] + assert ( + self.multimodal_cfg['image_aspect_ratio'] == 'square' + ), 'NeMo image transform with setting `image_aspect_ratio` to `square`.' + image = self.processor(image) images.append(image) images_tensors = torch.tensor([]) if images: @@ -545,7 +594,12 @@ def expand2square(pil_img, background_color): cur_token_len = (images_tensors[0].shape[1] // 14) * ( images_tensors[0].shape[2] // 14 ) # FIXME: 14 is hardcoded patch size - sources = preprocess_multimodal(copy.deepcopy(sources), self.multimodal_cfg, cur_token_len) + sources = preprocess_multimodal( + copy.deepcopy(sources), + self.multimodal_cfg, + cur_token_len, + use_plain=(self.conv_template == "plain"), + ) else: images_tensors = torch.tensor([]) sources = copy.deepcopy(sources) @@ -556,6 +610,8 @@ def expand2square(pil_img, background_color): data_dict = preprocess_v1(sources, self.tokenizer, self.multimodal_cfg,) elif self.conv_template == "llama_2": data_dict = preprocess_llama_2(sources, self.tokenizer, self.multimodal_cfg,) + elif self.conv_template == "plain": + data_dict = preprocess_plain(sources, self.tokenizer, self.multimodal_cfg,) else: raise ValueError(f"Conversation template `{self.conv_template}` is not supported in Neva now.") @@ -564,10 +620,13 @@ def expand2square(pil_img, background_color): # image exist in the data if self.multimodal_cfg['is_multimodal']: - crop_size = self.processor.crop_size + if isinstance(self.processor, CLIPImageProcessor): + crop_size = [self.processor.crop_size['height'], self.processor.crop_size['width']] + else: + crop_size = self.multimodal_cfg['crop_size'] # image does not exist in the data, but the model is multimodal zero_padding = torch.zeros( - (MAX_NUM_IMAGES - len(images_tensors), 3, crop_size['height'], crop_size['width']), dtype=torch.float + (MAX_NUM_IMAGES - len(images_tensors), 3, crop_size[0], crop_size[1]), dtype=torch.float ) images_tensors = torch.cat((images_tensors, zero_padding), dim=0) data_dict['image'] = images_tensors @@ -669,15 +728,15 @@ def make_supervised_data_module(tokenizer, model_cfg) -> Dict: add_extra_token = 1 if getattr(model_cfg, 'no_seqlen_plus_one_input_tokens', False): add_extra_token = 0 + crop_size = data_cfg.get("crop_size", (224, 224)) if mm_cfg.vision_encoder.from_hf: image_processor = CLIPImageProcessor.from_pretrained( mm_cfg.vision_encoder.from_pretrained, torch_dtype=torch.bfloat16 ) else: # TODO(yuya): Fix this hard-code for our own CLIP - image_processor = CLIPImageProcessor.from_pretrained( - "openai/clip-vit-large-patch14", torch_dtype=torch.bfloat16 - ) + image_processor = image_transform(crop_size, is_train=False, mean=None, std=None,) + train_dataset = NevaDataset( tokenizer=tokenizer, data_path=data_cfg.data_path, @@ -685,6 +744,7 @@ def make_supervised_data_module(tokenizer, model_cfg) -> Dict: is_multimodal=data_cfg.is_multimodal, sep_image_conv_front=data_cfg.sep_image_conv_front, conv_template=data_cfg.get("conv_template", "nvgpt"), + crop_size=crop_size, image_token_len=data_cfg.image_token_len, image_folder=data_cfg.image_folder, image_aspect_ratio=data_cfg.image_aspect_ratio, @@ -694,5 +754,5 @@ def make_supervised_data_module(tokenizer, model_cfg) -> Dict: context_length=model_cfg.encoder_seq_length, ), ) - # data_collator = DataCollatorForSupervisedDataset(tokenizer=tokenizer) + return dict(train_dataset=train_dataset, eval_dataset=train_dataset) diff --git a/nemo/collections/multimodal/data/stable_diffusion/stable_diffusion_dataset.py b/nemo/collections/multimodal/data/stable_diffusion/stable_diffusion_dataset.py index 445932124718..e4f3dea59169 100644 --- a/nemo/collections/multimodal/data/stable_diffusion/stable_diffusion_dataset.py +++ b/nemo/collections/multimodal/data/stable_diffusion/stable_diffusion_dataset.py @@ -183,3 +183,43 @@ def transform_fn(sample): ) return train_data, val_data + + +def build_train_valid_precached_clip_datasets(model_cfg, consumed_samples): + data_cfg = model_cfg.data + + # This function maps data that are tuples to dictionary. + def tuple_to_dict(inp): + for input in inp: + out_dict = dict() + out_dict[model_cfg.first_stage_key] = input[0] + out_dict[model_cfg.cond_stage_key] = input[1] + yield out_dict + + def transform_fn(sample): + latents, text_embed = sample["pyd"]["image_embed"], sample["pyd"]['captions_embed'] + latents = torch.from_numpy(latents) + text_embed = torch.from_numpy(text_embed) + + # latents are of shape ([4, 64, 64]) + return latents, text_embed + + train_data = WebDatasetCommon( + dataset_cfg=data_cfg, + consumed_samples=consumed_samples, + map_fn=transform_fn, + compose_fn=tuple_to_dict, + is_train=True, + ) + + val_data = None + if data_cfg.get("validation") is not None and data_cfg.validation.get("data_path"): + val_data = WebDatasetCommon( + dataset_cfg=data_cfg, + consumed_samples=consumed_samples, + map_fn=transform_fn, + compose_fn=tuple_to_dict, + is_train=False, + ) + + return train_data, val_data diff --git a/nemo/collections/multimodal/models/multimodal_llm/neva/neva_model.py b/nemo/collections/multimodal/models/multimodal_llm/neva/neva_model.py index 1a38d86742b4..5fd0fa830dd0 100644 --- a/nemo/collections/multimodal/models/multimodal_llm/neva/neva_model.py +++ b/nemo/collections/multimodal/models/multimodal_llm/neva/neva_model.py @@ -13,7 +13,6 @@ # limitations under the License. import os -import tempfile from functools import partial from itertools import chain from typing import Any, Optional @@ -25,9 +24,8 @@ from pytorch_lightning.trainer.trainer import Trainer from transformers import CLIPVisionModel +from nemo.collections.multimodal.data.neva.conversation import DEFAULT_IM_END_TOKEN, DEFAULT_IM_START_TOKEN from nemo.collections.multimodal.data.neva.neva_dataset import ( - DEFAULT_IM_END_TOKEN, - DEFAULT_IM_START_TOKEN, DataCollatorForSupervisedDataset, make_supervised_data_module, ) @@ -35,13 +33,10 @@ CLIPVisionTransformer, MegatronCLIPModel, ) -from nemo.collections.multimodal.parts.utils import extend_instance -from nemo.collections.nlp.data.language_modeling.megatron.data_samplers import ( - MegatronPretrainingRandomSampler, - MegatronPretrainingSampler, -) +from nemo.collections.multimodal.parts.utils import extend_instance, load_nemo_model_weights +from nemo.collections.nlp.data.language_modeling.megatron.data_samplers import MegatronPretrainingSampler from nemo.collections.nlp.models.language_modeling.megatron.gpt_model import GPTModel -from nemo.collections.nlp.models.language_modeling.megatron_gpt_model import MegatronGPTModel +from nemo.collections.nlp.models.language_modeling.megatron_gpt_model import MegatronGPTModel, get_specs from nemo.collections.nlp.models.nlp_model import NLPModel from nemo.collections.nlp.modules.common.megatron.adapters.parallel_adapters import ( AdapterName, @@ -57,11 +52,20 @@ ) from nemo.collections.nlp.modules.common.transformer.text_generation import LengthParam, OutputType, SamplingParam from nemo.collections.nlp.parts.mixins.multimodal_adapter_mixins import MultimodalAdapterModelMixin -from nemo.collections.nlp.parts.nlp_overrides import NLPSaveRestoreConnector from nemo.collections.nlp.parts.utils_funcs import get_last_rank +from nemo.collections.vision.data.megatron.data_samplers import MegatronVisionPretrainingRandomSampler from nemo.core import adapter_mixins from nemo.core.classes.common import PretrainedModelInfo -from nemo.utils import AppState, logging +from nemo.utils import logging + +try: + import apex.transformer.pipeline_parallel.utils + + HAVE_APEX = True + +except (ImportError, ModuleNotFoundError): + + HAVE_APEX = False try: from megatron.core import InferenceParams, dist_checkpointing, parallel_state @@ -82,6 +86,7 @@ def __init__(self, model_cfg, model_parallel_config, pre_process=True, post_proc model_cfg, model_parallel_config, pre_process=pre_process, post_process=post_process, skip_head=True, ) self.frozen = False + self.dtype = self.config.params_dtype def train(self, mode): if self.frozen: @@ -239,7 +244,7 @@ def __init__( self.media_start_id = media_start_id self.media_end_id = media_end_id self.mcore_gpt = mcore_gpt - self.dist_ckpt = False + self.is_dist_ckpt = False if getattr(self, 'language_model', None) is not None: self.embedding = self.language_model.embedding @@ -287,48 +292,10 @@ def _load_model_weights(self, nemo_path): """ Shared method to load model weights from a given nemo_path. """ - if torch.cuda.is_available(): - map_location = torch.device('cuda') - else: - map_location = torch.device('cpu') - - save_restore_connector = NLPSaveRestoreConnector() - cwd = os.getcwd() - app_state = AppState() - - with tempfile.TemporaryDirectory() as tmpdir: - try: - if os.path.isfile(nemo_path): - save_restore_connector._unpack_nemo_file(path2file=nemo_path, out_folder=tmpdir) - else: - tmpdir = nemo_path - os.chdir(tmpdir) - if app_state.model_parallel_size is not None and app_state.model_parallel_size > 1: - model_weights = save_restore_connector._inject_model_parallel_rank_for_ckpt( - tmpdir, save_restore_connector.model_weights_ckpt - ) - else: - model_weights = os.path.join(tmpdir, save_restore_connector.model_weights_ckpt) - - state_dict = save_restore_connector._load_state_dict_from_disk( - model_weights, map_location=map_location - ) - - # distributed checkpointing - if state_dict is None: - self.dist_ckpt = True - sharded_state_dict = self.sharded_state_dict(prefix="model.") - checkpoint = dict(state_dict=sharded_state_dict) - tmp_model_weights_ckpt = os.path.join(tmpdir, save_restore_connector.model_weights_ckpt) - tmp_model_weights_dir = os.path.splitext(tmp_model_weights_ckpt)[0] - assert os.path.isdir(tmp_model_weights_dir), f'Expected {tmp_model_weights_dir} to be a directory.' - checkpoint = dist_checkpointing.load( - sharded_state_dict=checkpoint, checkpoint_dir=tmp_model_weights_dir, - ) - state_dict = checkpoint["state_dict"] - - finally: - os.chdir(cwd) + sharded_state_dict = None + if getattr(self, "sharded_state_dict", None) is not None: + sharded_state_dict = self.sharded_state_dict(prefix="model.") + state_dict, self.is_dist_ckpt = load_nemo_model_weights(nemo_path, sharded_state_dict) return state_dict @@ -352,7 +319,7 @@ def load_llm_weights(self, nemo_path): state_dict = self._load_model_weights(nemo_path) new_state_dict = {} - if self.dist_ckpt or self.mcore_gpt: + if self.is_dist_ckpt or self.mcore_gpt: for k, v in state_dict.items(): new_k = k if k.startswith("model."): @@ -508,6 +475,7 @@ def dummy(): media_end_id=media_end_id, mcore_gpt=self.mcore_gpt, config=self.transformer_config, + transformer_layer_spec=get_specs(self.spec_name), vocab_size=self.cfg.get('override_vocab_size', self.padded_vocab_size), max_sequence_length=self.cfg.get('encoder_seq_length', 512), pre_process=pre_process, @@ -517,6 +485,7 @@ def dummy(): position_embedding_type=self.cfg.get('position_embedding_type', 'learned_absolute'), rotary_percent=self.cfg.get('rotary_percentage', 1.0), seq_len_interpolation_factor=self.cfg.get('seq_len_interpolation_factor', None), + rotary_base=self.cfg.get('rotary_base', 10000), ) else: model = NevaModel( @@ -602,6 +571,33 @@ def setup_optimizer_param_groups(self): params_with_grad = [param for param in param_group['params'] if param.requires_grad] param_group['params'] = params_with_grad + # set projection matrix and lora to two param groups with different LR + if self.use_peft: + assert len(self._optimizer_param_groups) == 1 + assert len(self.adapter_keys) == len(self._optimizer_param_groups[0]['params']) + # Mapping from parameter objects to their names + param_to_name = { + param: name + for name, param in self.model.named_parameters() + if name or name.replace("model.module.", "model.", "1") in self.adapter_keys + } + # Match the parameters and separate them into two groups + group1_params, group2_params = [], [] + for param in self._optimizer_param_groups[0]['params']: + param_name = param_to_name.get(param) + if 'mm_projector' in param_name: + group2_params.append(param) + else: + group1_params.append(param) + + base_lr = self._cfg.optim.get('lr') + mm_projector_lr_ratio = 0.1 # hard-coded ratio + # Create two new optimizer param groups + self._optimizer_param_groups = [ + {'params': group1_params, 'lr': base_lr}, + {'params': group2_params, 'lr': base_lr * mm_projector_lr_ratio}, + ] + def forward(self, tokens, text_position_ids, attention_mask, labels, media=None): forward_args = { 'input_ids': tokens, @@ -893,13 +889,15 @@ def build_pretraining_data_loader( pad_samples_to_global_batch_size=pad_samples_to_global_batch_size, ) elif self.cfg.data.dataloader_type == 'cyclic': - batch_sampler = MegatronPretrainingRandomSampler( + batch_sampler = MegatronVisionPretrainingRandomSampler( + dataset=dataset, total_samples=len(dataset), consumed_samples=consumed_samples, micro_batch_size=self.cfg.micro_batch_size, data_parallel_rank=parallel_state.get_data_parallel_rank(), data_parallel_size=parallel_state.get_data_parallel_world_size(), drop_last=self.cfg.get('drop_last', True), + data_sharding=False, ) else: raise ValueError('cfg.data.dataloader_type must be "single" or "cyclic"') @@ -1021,12 +1019,7 @@ def dummy(): if length_params is None: length_params = get_default_length_params() - import time - - start = time.time() # Supports only one prompt at a time result = megatron_neva_generate(self.cuda(), input_prompts, length_params, sampling_params, inference_config) - end = time.time() - print(f'Time taken {end - start}') return result diff --git a/nemo/collections/multimodal/models/text_to_image/dreambooth/dreambooth.py b/nemo/collections/multimodal/models/text_to_image/dreambooth/dreambooth.py index 492347f08524..ce82da9bd171 100644 --- a/nemo/collections/multimodal/models/text_to_image/dreambooth/dreambooth.py +++ b/nemo/collections/multimodal/models/text_to_image/dreambooth/dreambooth.py @@ -20,15 +20,19 @@ from torch._inductor import config as inductor_config from nemo.collections.multimodal.data.dreambooth.dreambooth_dataset import DreamBoothDataset +from nemo.collections.multimodal.modules.stable_diffusion.attention import LinearWrapper from nemo.collections.multimodal.modules.stable_diffusion.distributions.distributions import ( DiagonalGaussianDistribution, ) +from nemo.collections.multimodal.modules.stable_diffusion.encoders.modules import LoraWrapper from nemo.collections.multimodal.parts.utils import randn_like from nemo.collections.nlp.data.language_modeling.megatron.data_samplers import MegatronPretrainingRandomSampler from nemo.collections.nlp.models.language_modeling.megatron_base_model import MegatronBaseModel from nemo.collections.nlp.modules.common.megatron.module import Float16Module +from nemo.collections.nlp.parts.mixins.nlp_adapter_mixins import NLPAdapterModelMixin from nemo.collections.nlp.parts.utils_funcs import get_last_rank from nemo.core.classes.common import Serialization +from nemo.core.classes.mixins.adapter_mixins import AdapterModuleMixin from nemo.utils import logging try: @@ -124,8 +128,11 @@ def instantiate_text_encoder(self, cfg): model = DreamBooth.from_config_dict(cfg) if self.train_text_encoder: self.text_encoder = model.train() - for param in self.text_encoder.parameters(): - param.requires_grad = True + if (not hasattr(model, 'lora_layers')) or len( + model.lora_layers + ) == 0: # if no lora, train all the parameters + for param in self.text_encoder.parameters(): + param.requires_grad = True else: self.text_encoder = model.eval() self.text_encoder.train = disabled_train @@ -187,7 +194,7 @@ def set_input_tensor(self, input_tensor): pass -class MegatronDreamBooth(MegatronBaseModel): +class MegatronDreamBooth(NLPAdapterModelMixin, MegatronBaseModel): def __init__(self, cfg: DictConfig, trainer: Trainer): if not HAVE_APEX: raise ImportError( @@ -447,6 +454,7 @@ def setup(self, stage=None): self._micro_batch_size = self.cfg.micro_batch_size self.setup_training_data(self.cfg.data) + self.setup_complete = True def setup_training_data(self, cfg): if self.cfg.with_prior_preservation: @@ -637,3 +645,19 @@ def load_from_checkpoint( finally: cls._set_model_restore_state(is_being_restored=False) return checkpoint + + def _check_and_add_adapter(self, name, module, peft_name, peft_cfg, name_key_to_mcore_mixins=None): + if isinstance(module, AdapterModuleMixin): + if isinstance(module, LinearWrapper): + peft_cfg.in_features, peft_cfg.out_features = module.in_features, module.out_features + elif isinstance(module, LoraWrapper): + peft_cfg.in_features, peft_cfg.out_features = module.in_features, module.out_features + else: + return + if model_utils.import_class_by_path(peft_cfg._target_) in module.get_accepted_adapter_types(): + module.add_adapter( + name=peft_name, + cfg=peft_cfg, + base_model_cfg=self.cfg, + model_parallel_config=self.model_parallel_config, + ) diff --git a/nemo/collections/multimodal/models/text_to_image/stable_diffusion/ldm/autoencoder.py b/nemo/collections/multimodal/models/text_to_image/stable_diffusion/ldm/autoencoder.py index 1dd695af86f5..3a929ddd6829 100644 --- a/nemo/collections/multimodal/models/text_to_image/stable_diffusion/ldm/autoencoder.py +++ b/nemo/collections/multimodal/models/text_to_image/stable_diffusion/ldm/autoencoder.py @@ -318,7 +318,6 @@ def __init__( colorize_nlabels=None, monitor=None, from_pretrained: str = None, - capture_cudagraph_iters=-1, ): super().__init__() self.image_key = image_key @@ -339,17 +338,14 @@ def __init__( if from_pretrained is not None: state_dict = torch.load(from_pretrained) - self._load_pretrained_model(state_dict) - - # CUDA graph captured sub-modules - self.capture_cudagraph_iters = capture_cudagraph_iters - self.stream = torch.cuda.Stream() - self.encoder_iterations = self.decoder_iterations = 0 - self.encoder_graph = torch.cuda.CUDAGraph() # eval - self.decoder_graph = torch.cuda.CUDAGraph() # eval - self.graphed_encoder = self.graphed_decoder = None # train - self.static_x = self.static_moments = None - self.static_z = self.static_dec = None + missed_key, unexpected_key, missmatched_key, err_msg = self._load_pretrained_model(state_dict) + + if len(missed_key) > 0: + print( + f'{self.__class__.__name__}: Following keys are missing during loading unet weights, which may lead to compromised image quality for a resumed training. Please check the checkpoint you provided.' + ) + print("missed key: ", missed_key) + print("unexpected key: ", unexpected_key) def _state_key_mapping(self, state_dict: dict): import re diff --git a/nemo/collections/multimodal/models/text_to_image/stable_diffusion/ldm/ddpm.py b/nemo/collections/multimodal/models/text_to_image/stable_diffusion/ldm/ddpm.py index 89063f2490cc..31b56443846f 100644 --- a/nemo/collections/multimodal/models/text_to_image/stable_diffusion/ldm/ddpm.py +++ b/nemo/collections/multimodal/models/text_to_image/stable_diffusion/ldm/ddpm.py @@ -12,8 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. import itertools +import os +import time from functools import partial -from typing import Any, Optional +from typing import Any, Dict, List, Optional, Union import numpy as np import pytorch_lightning as pl @@ -31,8 +33,10 @@ from torchvision.utils import make_grid from tqdm import tqdm +from nemo.collections.multimodal.data.common.utils import get_collate_fn from nemo.collections.multimodal.data.stable_diffusion.stable_diffusion_dataset import ( build_train_valid_datasets, + build_train_valid_precached_clip_datasets, build_train_valid_precached_datasets, ) from nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.autoencoder import ( @@ -41,6 +45,7 @@ VQModelInterface, ) from nemo.collections.multimodal.models.text_to_image.stable_diffusion.samplers.ddim import DDIMSampler +from nemo.collections.multimodal.modules.stable_diffusion.attention import LinearWrapper from nemo.collections.multimodal.modules.stable_diffusion.diffusionmodules.util import ( extract_into_tensor, make_beta_schedule, @@ -50,6 +55,7 @@ DiagonalGaussianDistribution, normal_kl, ) +from nemo.collections.multimodal.modules.stable_diffusion.encoders.modules import LoraWrapper from nemo.collections.multimodal.parts.stable_diffusion.utils import ( count_params, default, @@ -62,9 +68,12 @@ from nemo.collections.multimodal.parts.utils import randn_like from nemo.collections.nlp.models.language_modeling.megatron_base_model import MegatronBaseModel from nemo.collections.nlp.modules.common.megatron.module import Float16Module +from nemo.collections.nlp.parts.mixins.nlp_adapter_mixins import NLPAdapterModelMixin +from nemo.collections.nlp.parts.peft_config import PEFT_CONFIG_MAP, PEFTConfig from nemo.collections.nlp.parts.utils_funcs import get_last_rank from nemo.core.classes.common import Serialization -from nemo.utils import logging +from nemo.core.classes.mixins.adapter_mixins import AdapterModuleMixin +from nemo.utils import logging, model_utils try: from apex import amp @@ -127,13 +136,7 @@ def __init__(self, cfg): self.channels = cfg.channels self.channels_last = cfg.get("channels_last", False) self.use_positional_encodings = cfg.use_positional_encodings - self.model = DiffusionWrapper( - cfg.unet_config, - cfg.conditioning_key, - cfg.inductor, - cfg.inductor_cudagraphs, - cfg.get("capture_cudagraph_iters", -1), - ) + self.model = DiffusionWrapper(cfg.unet_config, cfg.conditioning_key, cfg.inductor, cfg.inductor_cudagraphs) self.model_type = None count_params(self.model, verbose=True) @@ -157,7 +160,13 @@ def __init__(self, cfg): if self.learn_logvar: self.logvar = nn.Parameter(self.logvar, requires_grad=True) - self.rng = torch.Generator(device=torch.cuda.current_device(),) + cuda_graph_enabled = cfg.get("capture_cudagraph_iters", -1) >= 0 + if not cuda_graph_enabled: + logging.info("Use custom random generator") + self.rng = torch.Generator(device=torch.cuda.current_device(),) + else: + logging.info("Use system random generator since CUDA graph enabled") + self.rng = None def register_schedule( self, @@ -229,7 +238,9 @@ def register_schedule( self.register_buffer('lvlb_weights', lvlb_weights, persistent=False) assert not torch.isnan(self.lvlb_weights).all() - def init_from_ckpt(self, path, ignore_keys=list(), only_model=False): + def init_from_ckpt( + self, path, ignore_keys=list(), only_model=False, load_vae=True, load_unet=True, load_encoder=True, + ): pl_sd = torch.load(path, map_location="cpu") if "state_dict" in list(pl_sd.keys()): pl_sd = pl_sd["state_dict"] @@ -246,12 +257,45 @@ def init_from_ckpt(self, path, ignore_keys=list(), only_model=False): new_k = new_k.lstrip("model.") sd[new_k] = v + logging.info(f"Loading {path}") + logging.info(f"It has {len(sd)} entries") + logging.info(f"Existing model has {len(self.state_dict())} entries") + keys = list(sd.keys()) for k in keys: for ik in ignore_keys: if k.startswith(ik): - logging.info("Deleting key {} from state_dict.".format(k)) + logging.info("Deleting ignored key {} from state_dict.".format(k)) + del sd[k] + + if not load_vae: + deleted = 0 + keys = list(sd.keys()) + for k in keys: + if k.startswith("first_stage_model"): + deleted += 1 + del sd[k] + logging.info(f"Deleted {deleted} keys from `first_stage_model` state_dict.") + + if not load_encoder: + deleted = 0 + keys = list(sd.keys()) + for k in keys: + if k.startswith("cond_stage_model"): + deleted += 1 + logging.info("Deleting ignored key {} from state_dict.".format(k)) + del sd[k] + logging.info(f"Deleted {deleted} keys from `cond_stage_model` state_dict.") + + if not load_unet: + deleted = 0 + keys = list(sd.keys()) + for k in keys: + if k.startswith("model.diffusion_model"): + deleted += 1 del sd[k] + logging.info(f"Deleted {deleted} keys from `cond_stage_model` state_dict.") + missing, unexpected = ( self.load_state_dict(sd, strict=False) if not only_model else self.model.load_state_dict(sd, strict=False) ) @@ -513,7 +557,13 @@ def __init__(self, cfg, model_parallel_config): self.restarted_from_ckpt = False if ckpt_path is not None: - self.init_from_ckpt(ckpt_path, ignore_keys) + load_vae = True if cfg.load_vae is None else cfg.load_vae + load_unet = True if cfg.load_unet is None else cfg.load_unet + load_encoder = True if cfg.load_encoder is None else cfg.load_encoder + + self.init_from_ckpt( + ckpt_path, ignore_keys, load_vae=load_vae, load_unet=load_unet, load_encoder=load_encoder, + ) self.restarted_from_ckpt = True if self.channels_last: @@ -725,7 +775,13 @@ def get_input( if self.first_stage_key.endswith('encoded'): gaussian_parameters = batch[self.first_stage_key] encoder_posterior = DiagonalGaussianDistribution(gaussian_parameters) + elif self.first_stage_key.endswith('moments'): + # Loading distribution from disk and sampling encoded + distribution = batch[self.first_stage_key] # torch.size([3, 1, 8, 64, 64]) + distribution = torch.squeeze(distribution, dim=1) + encoder_posterior = DiagonalGaussianDistribution(distribution) else: + # Loading images from disk and encoding them x = super().get_input(batch, k) if bs is not None: x = x[:bs] @@ -1597,7 +1653,7 @@ def set_input_tensor(self, input_tensor): pass -class MegatronLatentDiffusion(MegatronBaseModel): +class MegatronLatentDiffusion(NLPAdapterModelMixin, MegatronBaseModel): """Megatron LatentDiffusion Model.""" def __init__(self, cfg: DictConfig, trainer: Trainer): @@ -1632,6 +1688,9 @@ def __init__(self, cfg: DictConfig, trainer: Trainer): else: raise ValueError('precision must be in ["32-true", "16-mixed", "bf16-mixed"]') + self.log_train_loss = bool(int(os.getenv("NEMO_LOG_TRAIN_LOSS", 1))) + self.loss_broadcast_src_rank = None + def get_module_list(self): if isinstance(self.model, list): return [model.module if isinstance(model, Float16Module) else model for model in self.model] @@ -1703,6 +1762,22 @@ def fwd_bwd_step(self, dataloader_iter, batch_idx, forward_only): else: loss_mean = torch.tensor(0.0, device=torch.cuda.current_device()) + if self.log_train_loss: + # When using pipeline parallelism, loss is calculated only in the last pipeline stage and + # it should be casted to other pipeline stages for logging. + # we can avoid this broadcast by updating the PTL log function to accept specific ranks + if parallel_state.get_pipeline_model_parallel_world_size() > 1: + if self.loss_broadcast_src_rank is None: + dp_size = parallel_state.get_data_parallel_world_size() + tp_size = parallel_state.get_tensor_model_parallel_world_size() + pp_size = parallel_state.get_pipeline_model_parallel_world_size() + rank_in_dp_tp_group = torch.distributed.get_rank() % (dp_size * tp_size) + last_pipeline_stage_offset = (tp_size * dp_size) * (pp_size - 1) + self.loss_broadcast_src_rank = last_pipeline_stage_offset + rank_in_dp_tp_group + torch.distributed.broadcast( + loss_mean, self.loss_broadcast_src_rank, group=parallel_state.get_pipeline_model_parallel_group(), + ) + return loss_mean, loss_dict def training_step(self, dataloader_iter, batch_idx): @@ -1720,8 +1795,6 @@ def training_step(self, dataloader_iter, batch_idx): loss_mean, loss_dict = self.fwd_bwd_step(dataloader_iter, batch_idx, False) - torch.distributed.broadcast(loss_mean, get_last_rank()) - # when using sequence parallelism, the sequence parallel layernorm grads must be all-reduced if self.cfg.get('tensor_model_parallel_size', 1) > 1 and self.cfg.get('sequence_parallel', False): self.allreduce_sequence_parallel_gradients() @@ -1740,13 +1813,30 @@ def training_step(self, dataloader_iter, batch_idx): # so we all-reduce gradients after the pipeline self.allreduce_gradients() # @sangkug we think this is causing memory to blow up (hurts perf) + # for cuda graph with pytorch lightning + # these values will be used outside the capturing range + if not hasattr(self, "loss_mean"): + self.loss_mean = torch.empty_like(loss_mean) + with torch.no_grad(): + self.loss_mean.copy_(loss_mean) + self.loss_dict = loss_dict + # this function is invoked by callback if with cuda graph, otherwise + # invoke it by ourselves + if self.cfg.get("capture_cudagraph_iters", -1) < 0: + self.non_cuda_graph_capturable() + + return loss_mean + + def non_cuda_graph_capturable(self): + if self.log_train_loss: + self.log('reduced_train_loss', self.loss_mean, prog_bar=True, rank_zero_only=True, batch_size=1) + if self.cfg.precision in [16, '16', '16-mixed']: loss_scale = self.trainer.precision_plugin.scaler._scale if loss_scale is not None: self.log('loss_scale', loss_scale, batch_size=1) - self.log_dict(loss_dict, prog_bar=False, logger=True, on_step=True, rank_zero_only=True, batch_size=1) - self.log('reduced_train_loss', loss_mean, prog_bar=True, rank_zero_only=True, batch_size=1) + self.log_dict(self.loss_dict, prog_bar=False, logger=True, on_step=True, rank_zero_only=True, batch_size=1) lr = self._optimizer.param_groups[0]['lr'] self.log('lr', lr, prog_bar=True, rank_zero_only=True, batch_size=1) self.log('global_step', self.trainer.global_step + 1, prog_bar=True, rank_zero_only=True, batch_size=1) @@ -1757,7 +1847,9 @@ def training_step(self, dataloader_iter, batch_idx): rank_zero_only=True, batch_size=1, ) - return loss_mean + + ts = torch.tensor(int(time.time() * 1e3), dtype=torch.float64) + self.log("timestamp", ts, batch_size=1, rank_zero_only=True) def backward(self, *args, **kwargs): """ LightningModule hook to do backward. @@ -1850,7 +1942,8 @@ def setup(self, stage=None): Args: stage (str, optional): Can be 'fit', 'validate', 'test' or 'predict'. Defaults to None. """ - self.model.rng.manual_seed(self.cfg.seed + 100 * parallel_state.get_data_parallel_rank()) + if self.model.rng: + self.model.rng.manual_seed(self.cfg.seed + 100 * parallel_state.get_data_parallel_rank()) # log number of parameters if isinstance(self.model, list): @@ -1890,16 +1983,22 @@ def setup(self, stage=None): self.setup_training_data(self.cfg.data) self.setup_validation_data(self.cfg.data) self.setup_test_data(self.cfg.data) + self.setup_complete = True def build_train_valid_test_datasets(self): - logging.info('Building datasets for Stable Diffusion...') + logging.info("Building datasets for Stable Diffusion...") if self.trainer.limit_val_batches > 1.0 and isinstance(self.trainer.limit_val_batches, float): raise ValueError("limit_val_batches must be an integer or float less than or equal to 1.0.") - if self.cfg.first_stage_key.endswith("encoded"): - self._train_ds, self._validation_ds = build_train_valid_precached_datasets( - model_cfg=self.cfg, consumed_samples=self.compute_consumed_samples(0), - ) + if self.cfg.first_stage_key.endswith("encoded") or self.cfg.first_stage_key.endswith("moments"): + if self.cfg.cond_stage_key.endswith("precached_clip"): + self._train_ds, self._validation_ds = build_train_valid_precached_clip_datasets( + model_cfg=self.cfg, consumed_samples=self.compute_consumed_samples(0), + ) + else: + self._train_ds, self._validation_ds = build_train_valid_precached_datasets( + model_cfg=self.cfg, consumed_samples=self.compute_consumed_samples(0), + ) else: self._train_ds, self._validation_ds = build_train_valid_datasets( model_cfg=self.cfg, consumed_samples=self.compute_consumed_samples(0) @@ -1921,6 +2020,13 @@ def setup_training_data(self, cfg): logging.info( f'Setting up train dataloader with len(len(self._train_ds)): {len(self._train_ds)} and consumed samples: {consumed_samples}' ) + if self.cfg.cond_stage_key.endswith("precached_clip"): + collate_fn = get_collate_fn( + first_stage_key=self.cfg.first_stage_key, cond_stage_key=self.cfg.cond_stage_key, + ) + else: + collate_fn = None + self._train_dl = torch.utils.data.DataLoader( self._train_ds, batch_size=self._micro_batch_size, @@ -1928,6 +2034,7 @@ def setup_training_data(self, cfg): pin_memory=True, drop_last=True, persistent_workers=True, + collate_fn=collate_fn, ) def setup_validation_data(self, cfg): @@ -2106,15 +2213,81 @@ def load_from_checkpoint( cls._set_model_restore_state(is_being_restored=False) return checkpoint + def _check_and_add_adapter(self, name, module, peft_name, peft_cfg, name_key_to_mcore_mixins=None): + if isinstance(module, AdapterModuleMixin): + if isinstance(module, LinearWrapper): + peft_cfg.in_features, peft_cfg.out_features = module.in_features, module.out_features + elif isinstance(module, LoraWrapper): + peft_cfg.in_features, peft_cfg.out_features = module.in_features, module.out_features + else: + return + if model_utils.import_class_by_path(peft_cfg._target_) in module.get_accepted_adapter_types(): + module.add_adapter( + name=peft_name, + cfg=peft_cfg, + base_model_cfg=self.cfg, + model_parallel_config=self.model_parallel_config, + ) + + def load_adapters( + self, filepath: str, peft_cfgs: Optional[Union[PEFTConfig, List[PEFTConfig]]] = None, map_location: str = None, + ): + """ + Utility method that restores only the adapter module(s), and not the entire model itself. + This allows the sharing of adapters which are often just a fraction of the size of the full model, + enabling easier deliver. + + .. note:: + + During restoration, assumes that the model does not currently already have one or more adapter modules. + + Args: + filepath: Filepath of the .ckpt or .nemo file. + peft_cfgs: One or more PEFTConfig objects that specify the PEFT method configuration. + If none, will infer from the .nemo checkpoint + map_location: Pytorch flag, where to place the adapter(s) state dict(s). + """ + + def _modify_state_dict(state_dict): + # Modify state key for Dreambooth inference + new_state_dict = {} + for key in state_dict.keys(): + new_key = key.replace('unet', 'model.diffusion_model') + new_key = new_key.replace('vae', 'first_stage_model') + new_key = new_key.replace('text_encoder', 'cond_stage_model') + new_key = new_key.replace('.noise_scheduler', '') + new_key = new_key.replace('._orig_mod', '') + new_state_dict[new_key] = state_dict[key] + state_dict = new_state_dict + return state_dict + + # Determine device + if map_location is None: + if torch.cuda.is_available(): + map_location = 'cuda' + else: + map_location = 'cpu' + + if filepath.endswith('.nemo'): + conf, state_dict = self._get_config_and_state_dict_from_nemo(filepath, map_location) + elif filepath.endswith('.ckpt'): + state_dict = torch.load(filepath, map_location)['state_dict'] + else: + raise RuntimeError(f"{filepath} is not nemo file or ckpt file") + if not peft_cfgs: + assert filepath.endswith( + '.nemo' + ), "Inferring peft scheme is only supported for .nemo checkpoints. Please supply the `peft_cfgs` argument." + peft_cfgs = [PEFT_CONFIG_MAP[conf.peft.peft_scheme](conf)] + self.add_adapter(peft_cfgs) + state_dict = _modify_state_dict(state_dict) + assert set(state_dict.keys()) == self.adapter_keys + super().load_state_dict(state_dict, strict=False) + class DiffusionWrapper(pl.LightningModule, Serialization): def __init__( - self, - diff_model_config, - conditioning_key, - inductor: bool = False, - inductor_cudagraphs: bool = False, - capture_cudagraph_iters: int = -1, + self, diff_model_config, conditioning_key, inductor: bool = False, inductor_cudagraphs: bool = False, ): super().__init__() self.diffusion_model = DiffusionWrapper.from_config_dict(diff_model_config) @@ -2128,10 +2301,6 @@ def __init__( torch._dynamo.config.automatic_dynamic_shapes = False inductor_config.triton.cudagraphs = inductor_cudagraphs self.diffusion_model = torch.compile(self.diffusion_model) - # CUDA graph - self.capture_cudagraph_iters = capture_cudagraph_iters - self.iterations = 0 - self.graphed_diffusion_model = None def forward(self, x, t, c_concat: list = None, c_crossattn: list = None): if self.conditioning_key is None: @@ -2141,15 +2310,7 @@ def forward(self, x, t, c_concat: list = None, c_crossattn: list = None): out = self.diffusion_model(xc, t) elif self.conditioning_key == 'crossattn': cc = torch.cat(c_crossattn, 1) - if self.iterations == self.capture_cudagraph_iters: - logging.info("Capturing CUDA graph for module: %s", self.diffusion_model.__class__.__name__) - self.graphed_diffusion_model = torch.cuda.make_graphed_callables(self.diffusion_model, (x, t, cc)) - - if 0 <= self.capture_cudagraph_iters <= self.iterations: - out = self.graphed_diffusion_model(x, t, cc) - else: - out = self.diffusion_model(x, t, context=cc) - self.iterations += 1 + out = self.diffusion_model(x, t, context=cc) elif self.conditioning_key == 'hybrid': xc = torch.cat([x] + c_concat, dim=1) cc = torch.cat(c_crossattn, 1) diff --git a/nemo/collections/multimodal/models/text_to_image/stable_diffusion/samplers/base_sampler.py b/nemo/collections/multimodal/models/text_to_image/stable_diffusion/samplers/base_sampler.py index b890d863428b..e1f2457f34de 100644 --- a/nemo/collections/multimodal/models/text_to_image/stable_diffusion/samplers/base_sampler.py +++ b/nemo/collections/multimodal/models/text_to_image/stable_diffusion/samplers/base_sampler.py @@ -117,6 +117,8 @@ def sample( # this has to come in the same format as the conditioning, # e.g. as encoded tokens, ... **kwargs, ): + self.verbose = verbose + if conditioning is not None: if isinstance(conditioning, dict): ctmp = conditioning[list(conditioning.keys())[0]] @@ -132,7 +134,8 @@ def sample( # sampling C, H, W = shape size = (batch_size, C, H, W) - print(f"Data shape for sampling is {size}, eta {eta}") + if self.verbose: + print(f"Data shape for sampling is {size}, eta {eta}") if self.sampler is Sampler.DPM: return self.dpm_sampling_fn( @@ -223,8 +226,13 @@ def sampling_fn( else: time_range = reversed(range(0, timesteps)) if ddim_use_original_steps else np.flip(timesteps) total_steps = timesteps if ddim_use_original_steps else timesteps.shape[0] - print(f"Running {self.sampler.name} Sampling with {total_steps} timesteps") - iterator = tqdm(time_range, desc=f"{self.sampler.name} Sampler", total=total_steps) + + if self.verbose: + print(f"Running {self.sampler.name} Sampling with {total_steps} timesteps") + iterator = tqdm(time_range, desc=f"{self.sampler.name} Sampler", total=total_steps) + else: + iterator = time_range + old_eps = [] for i, step in enumerate(iterator): index = total_steps - i - 1 diff --git a/nemo/collections/multimodal/modules/stable_diffusion/attention.py b/nemo/collections/multimodal/modules/stable_diffusion/attention.py index b2f211141065..e70a473d658b 100644 --- a/nemo/collections/multimodal/modules/stable_diffusion/attention.py +++ b/nemo/collections/multimodal/modules/stable_diffusion/attention.py @@ -22,6 +22,11 @@ from torch._dynamo import disable from nemo.collections.multimodal.modules.stable_diffusion.diffusionmodules.util import checkpoint +from nemo.collections.nlp.modules.common.megatron.adapters.parallel_adapters import ( + AdapterName, + ParallelLinearAdapterConfig, +) +from nemo.core import adapter_mixins def check_cuda(): @@ -82,7 +87,7 @@ def init_(tensor): class GEGLU(nn.Module): def __init__(self, dim_in, dim_out): super().__init__() - self.proj = nn.Linear(dim_in, dim_out * 2) + self.proj = LinearWrapper(dim_in, dim_out * 2) def forward(self, x): x, gate = self.proj(x).chunk(2, dim=-1) @@ -94,9 +99,9 @@ def __init__(self, dim, dim_out=None, mult=4, glu=False, dropout=0.0): super().__init__() inner_dim = int(dim * mult) dim_out = default(dim_out, dim) - project_in = nn.Sequential(nn.Linear(dim, inner_dim), nn.GELU()) if not glu else GEGLU(dim, inner_dim) + project_in = nn.Sequential(LinearWrapper(dim, inner_dim), nn.GELU()) if not glu else GEGLU(dim, inner_dim) - self.net = nn.Sequential(project_in, nn.Dropout(dropout), nn.Linear(inner_dim, dim_out)) + self.net = nn.Sequential(project_in, nn.Dropout(dropout), LinearWrapper(inner_dim, dim_out)) def forward(self, x): return self.net(x) @@ -184,10 +189,45 @@ def rearrange_heads_inner(t: torch.Tensor, h: int) -> torch.Tensor: return t.view(b, h, n, -1).transpose(1, 2).reshape(b, n, -1) +class LinearWrapper(nn.Linear, adapter_mixins.AdapterModuleMixin): + def __init__(self, in_features, out_features, bias=True, lora_network_alpha=None): + super().__init__(in_features, out_features, bias) + self.set_accepted_adapter_types([ParallelLinearAdapterConfig._target_]) + self.lora_network_alpha = lora_network_alpha + + def forward(self, x): + mixed_x = super().forward(x) + if self.is_adapter_available(): + lora_linear_adapter = self.get_adapter_module(AdapterName.PARALLEL_LINEAR_ADAPTER) + lora_mixed_x = lora_linear_adapter(x) + # This value has the same meaning as the `--network_alpha` option in the kohya-ss trainer script. + # See https://github.com/darkstorm2150/sd-scripts/blob/main/docs/train_network_README-en.md#execute-learning + if self.lora_network_alpha: + mixed_x = mixed_x + lora_mixed_x * (self.lora_network_alpha / lora_linear_adapter.dim) + else: + mixed_x = mixed_x + lora_mixed_x + return mixed_x + + def add_adapter(self, name, cfg, **kwargs): + self.lora_network_alpha = cfg.network_alpha + kwargs = {} + adapter_mixins.AdapterModuleMixin.add_adapter(self, name, cfg, **kwargs) + + class CrossAttention(nn.Module): - def __init__(self, query_dim, context_dim=None, heads=8, dim_head=64, dropout=0.0, use_flash_attention=False): + def __init__( + self, + query_dim, + context_dim=None, + heads=8, + dim_head=64, + dropout=0.0, + use_flash_attention=False, + lora_network_alpha=None, + ): super().__init__() - inner_dim = dim_head * heads + + self.inner_dim = dim_head * heads context_dim = default(context_dim, query_dim) # make attention part be aware of self-attention/cross-attention self.context_dim = context_dim @@ -197,11 +237,13 @@ def __init__(self, query_dim, context_dim=None, heads=8, dim_head=64, dropout=0. self.scale = dim_head ** -0.5 self.heads = heads - self.to_q = nn.Linear(query_dim, inner_dim, bias=False) - self.to_k = nn.Linear(context_dim, inner_dim, bias=False) - self.to_v = nn.Linear(context_dim, inner_dim, bias=False) + self.to_q = LinearWrapper(query_dim, self.inner_dim, bias=False, lora_network_alpha=lora_network_alpha) + self.to_k = LinearWrapper(context_dim, self.inner_dim, bias=False, lora_network_alpha=lora_network_alpha) + self.to_v = LinearWrapper(context_dim, self.inner_dim, bias=False, lora_network_alpha=lora_network_alpha) - self.to_out = nn.Sequential(nn.Linear(inner_dim, query_dim), nn.Dropout(dropout)) + self.to_out = nn.Sequential( + LinearWrapper(self.inner_dim, query_dim, lora_network_alpha=lora_network_alpha), nn.Dropout(dropout) + ) self.use_flash_attention = use_flash_attention if dim_head <= 160 and (dim_head % 8) == 0 and flash_attn_installed: @@ -292,6 +334,7 @@ def __init__( use_checkpoint=False, use_flash_attention=False, disable_self_attn=False, + lora_network_alpha=None, ): super().__init__() self.disable_self_attn = disable_self_attn @@ -302,6 +345,7 @@ def __init__( dropout=dropout, use_flash_attention=use_flash_attention, context_dim=context_dim if self.disable_self_attn else None, + lora_network_alpha=lora_network_alpha, ) # is a self-attention self.ff = FeedForward(dim, dropout=dropout, glu=gated_ff) self.attn2 = CrossAttention( @@ -311,6 +355,7 @@ def __init__( dim_head=d_head, dropout=dropout, use_flash_attention=use_flash_attention, + lora_network_alpha=lora_network_alpha, ) # is self-attn if context is none self.norm1 = nn.LayerNorm(dim) self.norm2 = nn.LayerNorm(dim) @@ -351,6 +396,7 @@ def __init__( use_linear=False, use_checkpoint=False, use_flash_attention=False, + lora_network_alpha=None, ): super().__init__() if exists(context_dim) and not isinstance(context_dim, list): @@ -375,6 +421,7 @@ def __init__( use_checkpoint=use_checkpoint, use_flash_attention=use_flash_attention, disable_self_attn=disable_self_attn, + lora_network_alpha=lora_network_alpha, ) for d in range(depth) ] diff --git a/nemo/collections/multimodal/modules/stable_diffusion/diffusionmodules/openaimodel.py b/nemo/collections/multimodal/modules/stable_diffusion/diffusionmodules/openaimodel.py index 1cf1798015eb..62842da602dc 100644 --- a/nemo/collections/multimodal/modules/stable_diffusion/diffusionmodules/openaimodel.py +++ b/nemo/collections/multimodal/modules/stable_diffusion/diffusionmodules/openaimodel.py @@ -470,6 +470,7 @@ def __init__( # It must be specified when from pretrained is not None. It indicates loading unet from NeMo trained ckpt or HF use_flash_attention: bool = False, enable_amp_o2_fp16: bool = False, + lora_network_alpha=None, ): super().__init__() if use_spatial_transformer: @@ -567,6 +568,7 @@ def __init__( use_linear=use_linear_in_transformer, use_checkpoint=use_checkpoint, use_flash_attention=use_flash_attention, + lora_network_alpha=lora_network_alpha, ) ) self.input_blocks.append(TimestepEmbedSequential(*layers)) @@ -631,6 +633,7 @@ def __init__( use_linear=use_linear_in_transformer, use_checkpoint=use_checkpoint, use_flash_attention=use_flash_attention, + lora_network_alpha=lora_network_alpha, ), ResBlock( ch, @@ -687,6 +690,7 @@ def __init__( use_linear=use_linear_in_transformer, use_checkpoint=use_checkpoint, use_flash_attention=use_flash_attention, + lora_network_alpha=lora_network_alpha, ) ) if level and i == num_res_blocks: @@ -722,7 +726,13 @@ def __init__( ) if from_pretrained is not None: - state_dict = torch.load(from_pretrained, map_location='cpu') + if from_pretrained.endswith('safetensors'): + from safetensors.torch import load_file as load_safetensors + + state_dict = load_safetensors(from_pretrained) + else: + state_dict = torch.load(from_pretrained, map_location='cpu') + if 'state_dict' in state_dict.keys(): state_dict = state_dict['state_dict'] missing_key, unexpected_keys, _, _ = self._load_pretrained_model(state_dict, from_NeMo=from_NeMo) @@ -854,10 +864,10 @@ def _state_key_mapping(self, state_dict: dict): return res_dict def _load_pretrained_model(self, state_dict, ignore_mismatched_sizes=False, from_NeMo=False): - if from_NeMo: - state_dict = self._strip_unet_key_prefix(state_dict) - else: + state_dict = self._strip_unet_key_prefix(state_dict) + if not from_NeMo: state_dict = self._state_key_mapping(state_dict) + model_state_dict = self.state_dict() loaded_keys = [k for k in state_dict.keys()] expected_keys = list(model_state_dict.keys()) @@ -912,14 +922,16 @@ def _strip_unet_key_prefix(self, state_dict): for key_, value_ in state_dict.items(): if key_.startswith('model.diffusion_model'): re_state_dict[key_.replace('model.diffusion_model.', '')] = value_ - if key_.startswith('model.model.diffusion_model'): + elif key_.startswith('model.model.diffusion_model'): re_state_dict[key_.replace('model.model.diffusion_model.', '')] = value_ - if key_.startswith('model._orig_mod.diffusion_model.'): + elif key_.startswith('model._orig_mod.diffusion_model.'): re_state_dict[key_.replace('model._orig_mod.diffusion_model.', '')] = value_ - if key_.startswith('model.model._orig_mod.diffusion_model.'): + elif key_.startswith('model.model._orig_mod.diffusion_model.'): re_state_dict[key_.replace('model.model._orig_mod.diffusion_model.', '')] = value_ - if key_.startswith('model.model.diffusion_model._orig_mod.'): + elif key_.startswith('model.model.diffusion_model._orig_mod.'): re_state_dict[key_.replace('model.model.diffusion_model._orig_mod.', '')] = value_ + else: + re_state_dict[key_] = value_ return re_state_dict def _load_state_dict_into_model(self, state_dict): diff --git a/nemo/collections/multimodal/modules/stable_diffusion/encoders/modules.py b/nemo/collections/multimodal/modules/stable_diffusion/encoders/modules.py index ec3bd82ba137..ca61f88fd901 100644 --- a/nemo/collections/multimodal/modules/stable_diffusion/encoders/modules.py +++ b/nemo/collections/multimodal/modules/stable_diffusion/encoders/modules.py @@ -28,8 +28,13 @@ TransformerWrapper, # TODO: can we directly rely on lucidrains code and simply add this as a reuirement? --> test ) from nemo.collections.multimodal.modules.stable_diffusion.encoders.x_transformer import Encoder +from nemo.collections.nlp.modules.common.megatron.adapters.parallel_adapters import ( + AdapterName, + ParallelLinearAdapterConfig, +) from nemo.collections.nlp.modules.common.tokenizer_utils import get_nmt_tokenizer from nemo.collections.nlp.parts.nlp_overrides import NLPSaveRestoreConnector +from nemo.core import adapter_mixins from nemo.utils import logging try: @@ -45,12 +50,37 @@ class AbstractEncoder(nn.Module): - def __init__(self): + def __init__(self, enable_lora_finetune=False, target_block=[], target_module=[]): super().__init__() + self.TARGET_BLOCK = target_block + self.TARGET_MODULE = target_module + if enable_lora_finetune: + self.lora_layers = [] def encode(self, *args, **kwargs): raise NotImplementedError + def _enable_lora(self, lora_model): + for module_name, module in lora_model.named_modules(): + if module.__class__.__name__ in self.TARGET_BLOCK: + tmp = {} + for sub_name, sub_module in module.named_modules(): + if sub_module.__class__.__name__ in self.TARGET_MODULE: + if hasattr(sub_module, "input_size") and hasattr( + sub_module, "output_size" + ): # for megatron ParallelLinear + lora = LoraWrapper(sub_module, sub_module.input_size, sub_module.output_size) + else: # for nn.Linear + lora = LoraWrapper(sub_module, sub_module.in_features, sub_module.out_features) + self.lora_layers.append(lora) + if sub_name not in tmp.keys(): + tmp.update({sub_name: lora}) + else: + print(f"Duplicate subnames are found in module {module_name}") + for sub_name, lora_layer in tmp.items(): + lora_name = f'{sub_name}_lora' + module.add_module(lora_name, lora_layer) + class ClassEmbedder(nn.Module): def __init__(self, embed_dim, n_classes=1000, key='class'): @@ -185,26 +215,60 @@ def encode(self, x): return self(x) +class LoraWrapper(nn.Module, adapter_mixins.AdapterModuleMixin): + def __init__(self, target_module, in_features, out_features, lora_network_alpha=None): + super().__init__() + self.target_module = target_module + self.set_accepted_adapter_types([ParallelLinearAdapterConfig._target_]) + self.lora_network_alpha = lora_network_alpha + self.in_features = in_features + self.out_features = out_features + + def forward(self, x): + org_results = self.target_forward(x) + if self.is_adapter_available(): + lora_linear_adapter = self.get_adapter_module(AdapterName.PARALLEL_LINEAR_ADAPTER) + lora_mixed_x = lora_linear_adapter(x) + # This value has the same meaning as the `--network_alpha` option in the kohya-ss trainer script. + # See https://github.com/darkstorm2150/sd-scripts/blob/main/docs/train_network_README-en.md#execute-learning + mixed_x = org_results[0] if isinstance(org_results, tuple) else org_results + + if self.lora_network_alpha: + mixed_x = mixed_x + lora_mixed_x * (self.lora_network_alpha / lora_linear_adapter.dim) + else: + mixed_x = mixed_x + lora_mixed_x + + if isinstance(org_results, tuple): + org_results = (mixed_x, *org_results[1:]) + else: + org_results = mixed_x + + return org_results + + def add_adapter(self, name, cfg, **kwargs): + self.lora_network_alpha = cfg.network_alpha + kwargs = {} + adapter_mixins.AdapterModuleMixin.add_adapter(self, name, cfg, **kwargs) + self.target_forward = self.target_module.forward + self.target_module.forward = self.forward + del self.target_module + + class FrozenCLIPEmbedder(AbstractEncoder): """Uses the CLIP transformer encoder for text (from Hugging Face)""" def __init__( - self, version="openai/clip-vit-large-patch14", device="cuda", max_length=77, capture_cudagraph_iters: int = -1 + self, version="openai/clip-vit-large-patch14", device="cuda", max_length=77, enable_lora_finetune=False ): - super().__init__() + super().__init__(enable_lora_finetune, target_block=["CLIPAttention", "CLIPMLP"], target_module=["Linear"]) self.tokenizer = CLIPTokenizer.from_pretrained(version) self.transformer = CLIPTextModel.from_pretrained(version) self.device = device self.max_length = max_length self.freeze() - - # CUDA graph captured sub-modules - self.capture_cudagraph_iters = capture_cudagraph_iters - self.iterations = 0 - self.stream = torch.cuda.Stream() - self.transformer_graph = torch.cuda.CUDAGraph() - self.static_tokens = None - self.static_outputs = None + if enable_lora_finetune: + self._enable_lora(self.transformer) + print(f"CLIP transformer encoder add {len(self.lora_layers)} lora layers.") def freeze(self): self.transformer = self.transformer.eval() @@ -221,35 +285,12 @@ def forward(self, text): padding="max_length", return_tensors="pt", ) - if self.capture_cudagraph_iters < 0: - tokens = batch_encoding["input_ids"].to(self.device, non_blocking=True) - outputs = self.transformer(input_ids=tokens) - z = outputs.last_hidden_state + tokens = batch_encoding["input_ids"].to(self.device, non_blocking=True) + outputs = self.transformer(input_ids=tokens) - else: - if self.static_tokens is None: - self.static_tokens = batch_encoding["input_ids"].to(device=self.device, non_blocking=True) - self.static_tokens.copy_(batch_encoding["input_ids"], non_blocking=True) - - if self.iterations == self.capture_cudagraph_iters: - # cuda graph capture - logging.info("Capturing CUDA graph for module: %s", self.transformer.__class__.__name__) - with torch.cuda.graph(self.transformer_graph): - self.static_outputs = self.transformer(input_ids=self.static_tokens) - - if 0 <= self.capture_cudagraph_iters <= self.iterations: - # cuda graph replay - self.transformer_graph.replay() - else: - # warmup - self.stream.wait_stream(torch.cuda.current_stream()) - with torch.cuda.stream(self.stream): - self.static_outputs = self.transformer(input_ids=self.static_tokens) - torch.cuda.current_stream().wait_stream(self.stream) - self.iterations += 1 - z = self.static_outputs.last_hidden_state + z = outputs.last_hidden_state - # # Pad the seq length to multiple of 8 + # Pad the seq length to multiple of 8 seq_len = (z.shape[1] + 8 - 1) // 8 * 8 z = torch.nn.functional.pad(z, (0, 0, 0, seq_len - z.shape[1]), value=0.0) return z @@ -278,10 +319,14 @@ def __init__( freeze=True, layer="last", use_fp16=False, + cache_dir=None, ): super().__init__() assert layer in self.LAYERS - model, _, _ = open_clip.create_model_and_transforms(arch, device=torch.device('cpu'), pretrained=version) + print(f"Downloading clip with", arch, version, cache_dir) + model, _, _ = open_clip.create_model_and_transforms( + arch, device=torch.device("cpu"), pretrained=version, cache_dir=cache_dir, + ) del model.visual self.model = model @@ -303,8 +348,12 @@ def freeze(self): param.requires_grad = False def forward(self, text): - tokens = open_clip.tokenize(text) - z = self.encode_with_transformer(tokens.to(self.device)) + if isinstance(text, list) and isinstance(text[0], str): + tokens = open_clip.tokenize(text) + else: + # tokenizer has been invoked before + tokens = text + z = self.encode_with_transformer(tokens.to(self.device, non_blocking=True)) return z def encode_with_transformer(self, text): @@ -331,8 +380,21 @@ def encode(self, text): class FrozenMegatronCLIPEmbedder(AbstractEncoder): - def __init__(self, restore_from_path, device="cuda", layer="last", freeze=True, cfg=None, use_fp16=False): - super().__init__() + def __init__( + self, + restore_from_path, + device="cuda", + layer="last", + freeze=True, + cfg=None, + use_fp16=False, + enable_lora_finetune=False, + ): + super().__init__( + enable_lora_finetune=enable_lora_finetune, + target_block=["ParallelAttention", "ParallelMLP"], + target_module=["ColumnParallelLinear", "RowParallelLinear"], + ) if restore_from_path is not None: cfg, state_dict = self.load_config_and_state_from_nemo(restore_from_path) elif cfg is not None: @@ -355,6 +417,10 @@ def __init__(self, restore_from_path, device="cuda", layer="last", freeze=True, else: raise NotImplementedError() + if enable_lora_finetune: + self._enable_lora(self.model.language_model) + print(f"Megatron CLIP encoder add {len(self.lora_layers)} lora layers.") + def freeze(self): self.model = self.model.eval() for param in self.parameters(): diff --git a/nemo/collections/multimodal/parts/stable_diffusion/pipeline.py b/nemo/collections/multimodal/parts/stable_diffusion/pipeline.py index e9de61d6025a..b28bfc6bcc5c 100644 --- a/nemo/collections/multimodal/parts/stable_diffusion/pipeline.py +++ b/nemo/collections/multimodal/parts/stable_diffusion/pipeline.py @@ -14,6 +14,8 @@ import os import pickle import time +from collections import defaultdict +from itertools import chain import torch from PIL import Image @@ -25,10 +27,10 @@ from nemo.collections.multimodal.parts.stable_diffusion.utils import DataParallelWrapper -def encode_prompt(cond_stage_model, prompt, unconditional_guidance_scale, batch_size): - c = cond_stage_model.encode(batch_size * [prompt]) +def encode_prompt(cond_stage_model, prompts, unconditional_guidance_scale): + c = cond_stage_model.encode(prompts) if unconditional_guidance_scale != 1.0: - uc = cond_stage_model.encode(batch_size * [""]) + uc = cond_stage_model.encode(len(prompts) * [""]) else: uc = None return c, uc @@ -73,10 +75,17 @@ def torch_to_numpy(images): return numpy_images +def pad_with_zeros(cond, u_cond, batch_size): + b, *shape = cond.shape + filler = torch.zeros(batch_size - b, *shape, device=cond.device) + return torch.cat([cond, filler]), torch.cat([u_cond, filler]) + + def pipeline(model, cfg, verbose=True, rng=None): # setup default values for inference configs unconditional_guidance_scale = cfg.infer.get("unconditional_guidance_scale", 7.5) - batch_size = cfg.infer.get('num_images_per_prompt', 1) + num_images_per_prompt = cfg.infer.get('num_images_per_prompt', 1) + batch_size = cfg.infer.get('batch_size', 1) prompts = cfg.infer.get('prompts', []) height = cfg.infer.get('height', 512) width = cfg.infer.get('width', 512) @@ -127,10 +136,16 @@ def pipeline(model, cfg, verbose=True, rng=None): if isinstance(prompts, str): prompts = [prompts] - for prompt in prompts: + multi_prompts = [p for p in prompts for _ in range(num_images_per_prompt)] + batched_prompts = [multi_prompts[i : i + batch_size] for i in range(0, len(multi_prompts), batch_size)] + # decrease batch_size if the number of imputs is lower than bs in the config + batch_size = min(len(batched_prompts[0]), batch_size) + + for batch in batched_prompts: tic = time.perf_counter() tic_total = tic - cond, u_cond = encode_prompt(model.cond_stage_model, prompt, unconditional_guidance_scale, batch_size) + cond, u_cond = encode_prompt(model.cond_stage_model, batch, unconditional_guidance_scale,) + cond, u_cond = pad_with_zeros(cond, u_cond, batch_size) toc = time.perf_counter() conditioning_time = toc - tic @@ -138,6 +153,7 @@ def pipeline(model, cfg, verbose=True, rng=None): latents = torch.randn( [batch_size, in_channels, height // downsampling_factor, width // downsampling_factor], generator=rng ).to(torch.cuda.current_device()) + assert len(cond) == len(latents), (len(cond), len(latents)) tic = time.perf_counter() samples, intermediates = sampler.sample( @@ -158,6 +174,8 @@ def pipeline(model, cfg, verbose=True, rng=None): tic = time.perf_counter() images = decode_images(model, samples) + # remove padding + images = images[: len(batch)] toc = time.perf_counter() decode_time = toc - tic @@ -186,9 +204,13 @@ def pipeline(model, cfg, verbose=True, rng=None): if save_to_file: os.makedirs(out_path, exist_ok=True) if output_type == 'pil': - for text_prompt, pils in zip(prompts, output): - for idx, image in enumerate(pils): - image.save(os.path.join(out_path, f'{text_prompt[:50]}_{idx}.png')) + prompts = chain.from_iterable(batched_prompts) + pils = chain.from_iterable(output) + counts = defaultdict(int) + for text_prompt, image in zip(prompts, pils): + idx = counts[text_prompt] + counts[text_prompt] += 1 + image.save(os.path.join(out_path, f'{text_prompt[:50]}_{idx}.png')) else: with open(os.path.join(out_path, 'output.pkl'), 'wb') as f: pickle.dump(output, f) diff --git a/nemo/collections/multimodal/parts/utils.py b/nemo/collections/multimodal/parts/utils.py index bb612db2ce46..c82e0cd37140 100644 --- a/nemo/collections/multimodal/parts/utils.py +++ b/nemo/collections/multimodal/parts/utils.py @@ -12,16 +12,28 @@ # See the License for the specific language governing permissions and # limitations under the License. import os +import tempfile from typing import Any, Callable, Tuple import torch -from omegaconf import DictConfig, open_dict +from omegaconf import DictConfig, OmegaConf, open_dict from PIL import Image from pytorch_lightning import Trainer from pytorch_lightning.plugins.environments import TorchElasticEnvironment +from transformers import CLIPImageProcessor from nemo.collections.nlp.parts.nlp_overrides import NLPDDPStrategy, NLPSaveRestoreConnector -from nemo.utils import logging +from nemo.collections.nlp.parts.peft_config import PEFT_CONFIG_MAP +from nemo.utils import AppState, logging + +try: + from megatron.core import dist_checkpointing + + HAVE_MEGATRON_CORE = True + +except (ImportError, ModuleNotFoundError): + + HAVE_MEGATRON_CORE = False def numpy_to_pil(images): @@ -84,6 +96,54 @@ def apply_with_stopping_condition(module, apply_fn, apply_condition=None, stoppi ) +def load_nemo_model_weights(nemo_path, sharded_state_dict=None): + """ + Shared method to load model weights from a given nemo_path. + """ + if torch.cuda.is_available(): + map_location = torch.device('cuda') + else: + map_location = torch.device('cpu') + + save_restore_connector = NLPSaveRestoreConnector() + cwd = os.getcwd() + app_state = AppState() + is_dist_ckpt = False + + with tempfile.TemporaryDirectory() as tmpdir: + try: + if os.path.isfile(nemo_path): + save_restore_connector._unpack_nemo_file(path2file=nemo_path, out_folder=tmpdir) + else: + tmpdir = nemo_path + os.chdir(tmpdir) + if app_state.model_parallel_size is not None and app_state.model_parallel_size > 1: + model_weights = save_restore_connector._inject_model_parallel_rank_for_ckpt( + tmpdir, save_restore_connector.model_weights_ckpt + ) + else: + model_weights = os.path.join(tmpdir, save_restore_connector.model_weights_ckpt) + + state_dict = save_restore_connector._load_state_dict_from_disk(model_weights, map_location=map_location) + + # distributed checkpointing + if state_dict is None and sharded_state_dict is not None: + is_dist_ckpt = True + checkpoint = dict(state_dict=sharded_state_dict) + tmp_model_weights_ckpt = os.path.join(tmpdir, save_restore_connector.model_weights_ckpt) + tmp_model_weights_dir = os.path.splitext(tmp_model_weights_ckpt)[0] + assert os.path.isdir(tmp_model_weights_dir), f'Expected {tmp_model_weights_dir} to be a directory.' + checkpoint = dist_checkpointing.load( + sharded_state_dict=checkpoint, checkpoint_dir=tmp_model_weights_dir, + ) + state_dict = checkpoint["state_dict"] + + finally: + os.chdir(cwd) + + return state_dict, is_dist_ckpt + + def setup_trainer_and_models_for_inference( model_provider: Any, cfg: DictConfig, model_cfg_modifier: Callable, ): @@ -253,3 +313,153 @@ def dummy(): # Return the trainer and model objects. return trainer, model + + +def create_neva_model_and_processor(cfg): + from nemo.collections.multimodal.models.multimodal_llm.neva.neva_model import MegatronNevaModel + + plugins = [] + if cfg.get('cluster_type', None) == 'BCP': + plugins.append(TorchElasticEnvironment()) + # trainer required for restoring model parallel models + trainer = Trainer(plugins=plugins, strategy=NLPDDPStrategy(), **cfg.trainer) + + if ( + cfg.tensor_model_parallel_size < 0 + or cfg.pipeline_model_parallel_size < 0 + or cfg.get('pipeline_model_parallel_split_rank', -1) < 0 + ): + model_config = MegatronNevaModel.restore_from( + restore_path=cfg.neva_model_file, trainer=trainer, return_config=True, + ) + + with open_dict(cfg): + cfg.tensor_model_parallel_size = model_config.get('tensor_model_parallel_size', 1) + cfg.pipeline_model_parallel_size = model_config.get('pipeline_model_parallel_size', 1) + cfg.pipeline_model_parallel_split_rank = model_config.get('pipeline_model_parallel_split_rank', 0) + + assert ( + cfg.trainer.devices * cfg.trainer.num_nodes + == cfg.tensor_model_parallel_size * cfg.pipeline_model_parallel_size + ), "devices * num_nodes should equal tensor_model_parallel_size * pipeline_model_parallel_size" + + if cfg.neva_model_file: + save_restore_connector = NLPSaveRestoreConnector() + if os.path.isdir(cfg.neva_model_file): + save_restore_connector.model_extracted_dir = cfg.neva_model_file + + neva_cfg = MegatronNevaModel.restore_from( + restore_path=cfg.neva_model_file, + trainer=trainer, + return_config=True, + save_restore_connector=save_restore_connector, + ) + OmegaConf.set_struct(neva_cfg, True) + with open_dict(neva_cfg): + neva_cfg.sequence_parallel = False + neva_cfg.activations_checkpoint_granularity = None + neva_cfg.activations_checkpoint_method = None + neva_cfg.precision = trainer.precision + neva_cfg.mm_cfg.llm.from_pretrained = cfg.get('base_model_file', None) + # neva_cfg.mm_cfg.vision_encoder.from_pretrained = None + + model = MegatronNevaModel.restore_from( + restore_path=cfg.neva_model_file, + trainer=trainer, + override_config_path=neva_cfg, + save_restore_connector=save_restore_connector, + ) + if neva_cfg.get('peft') is not None: + peft_cfg_cls = PEFT_CONFIG_MAP[neva_cfg.peft.peft_scheme] + if peft_cfg_cls is not None: + model.load_adapters(cfg.neva_model_file, peft_cfg_cls(neva_cfg)) + + elif cfg.checkpoint_dir: + app_state = AppState() + if cfg.tensor_model_parallel_size > 1 or cfg.pipeline_model_parallel_size > 1: + app_state.model_parallel_size = cfg.tensor_model_parallel_size * cfg.pipeline_model_parallel_size + app_state.tensor_model_parallel_size = cfg.tensor_model_parallel_size + app_state.pipeline_model_parallel_size = cfg.pipeline_model_parallel_size + ( + app_state.tensor_model_parallel_rank, + app_state.pipeline_model_parallel_rank, + app_state.model_parallel_size, + app_state.data_parallel_size, + app_state.pipeline_model_parallel_split_rank, + app_state.virtual_pipeline_model_parallel_rank, + ) = fake_initialize_model_parallel( + world_size=app_state.model_parallel_size, + rank=trainer.global_rank, + tensor_model_parallel_size_=cfg.tensor_model_parallel_size, + pipeline_model_parallel_size_=cfg.pipeline_model_parallel_size, + pipeline_model_parallel_split_rank_=cfg.pipeline_model_parallel_split_rank, + ) + checkpoint_path = inject_model_parallel_rank(os.path.join(cfg.checkpoint_dir, cfg.checkpoint_name)) + # TODO: This wont work properly (We need to set model.llm.from_pretrained model.vision.from_pretrained to nul) + model = MegatronNevaModel.load_from_checkpoint(checkpoint_path, hparams_file=cfg.hparams_file, trainer=trainer) + else: + raise ValueError("need at least a nemo file or checkpoint dir") + + model.freeze() + + # Have to turn off activations_checkpoint_method for inference + try: + model.model.language_model.encoder.activations_checkpoint_method = None + except AttributeError: + pass + try: + model.model.module.language_model.encoder.activations_checkpoint_method = None + except AttributeError: + pass + + def image_processor(maybe_image_path): + if isinstance(maybe_image_path, str): + image = Image.open(maybe_image_path).convert('RGB') + else: + image = maybe_image_path + + if neva_cfg.mm_cfg.vision_encoder.from_hf: + processor = CLIPImageProcessor.from_pretrained( + neva_cfg.mm_cfg.vision_encoder.from_pretrained, torch_dtype=torch.bfloat16 + ) + else: + processor = CLIPImageProcessor.from_pretrained("openai/clip-vit-large-patch14", torch_dtype=torch.bfloat16) + + if neva_cfg.data.image_aspect_ratio == 'keep': + max_hw, min_hw = max(image.size), min(image.size) + aspect_ratio = max_hw / min_hw + max_len, min_len = 448, 224 + shortest_edge = int(min(max_len / aspect_ratio, min_len)) + image = processor.preprocess( + image, return_tensors='pt', do_center_crop=False, size={"shortest_edge": shortest_edge} + )['pixel_values'][0] + elif neva_cfg.data.image_aspect_ratio == 'pad': + + def expand2square(pil_img, background_color): + width, height = pil_img.size + if width == height: + return pil_img + elif width > height: + result = Image.new(pil_img.mode, (width, width), background_color) + result.paste(pil_img, (0, (width - height) // 2)) + return result + else: + result = Image.new(pil_img.mode, (height, height), background_color) + result.paste(pil_img, ((height - width) // 2, 0)) + return result + + image = expand2square(image, tuple(int(x * 255) for x in processor.image_mean)) + image = processor.preprocess(image, return_tensors='pt')['pixel_values'][0] + else: + image = processor.preprocess(image, return_tensors='pt')['pixel_values'][0] + + if neva_cfg.precision in [16, '16', '16-mixed']: + media = image.type(torch.float16) + elif neva_cfg.precision in [32, '32', '32-true']: + media = image.type(torch.float32) + else: + media = image.type(torch.bfloat16) + + return media.unsqueeze(dim=0).unsqueeze(dim=0).unsqueeze(dim=0) + + return model, image_processor diff --git a/nemo/collections/nlp/modules/common/text_generation_strategy.py b/nemo/collections/nlp/modules/common/text_generation_strategy.py index b17dd12c0e3f..fd68eef592fd 100644 --- a/nemo/collections/nlp/modules/common/text_generation_strategy.py +++ b/nemo/collections/nlp/modules/common/text_generation_strategy.py @@ -20,7 +20,6 @@ from typing import List, Set, Tuple import torch -from transformers import CLIPImageProcessor from nemo.collections.nlp.modules.common.lm_utils import pad_batch from nemo.collections.nlp.modules.common.megatron.utils import get_ltor_masks_and_position_ids @@ -325,6 +324,65 @@ def prepare_batch_at_step( return batch, tensor_shape +def neva_process_prompts(prompt, tokenizer, multimodal_cfg, num_media_latents, conv_template): + from nemo.collections.multimodal.data.neva.neva_dataset import ( + DEFAULT_IMAGE_TOKEN, + preprocess_llama_2, + preprocess_multimodal, + preprocess_nvgpt, + preprocess_v1, + ) + + list_data_dict = [] + if multimodal_cfg["conv_template"] == "nvgpt": + record = { + 'system': 'A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user\'s questions.\n\n', + 'conversations': [{'from': 'User', 'value': prompt}, {'from': 'Assistant', 'value': '',},], + } + + for turn in record['conversations']: # + if turn.get('value') is not None: + turn['value'] = re.sub('', f'{DEFAULT_IMAGE_TOKEN}\n', turn['value']) + list_data_dict.append(record) + + sources = preprocess_multimodal( + copy.deepcopy(list_data_dict), multimodal_cfg, num_media_latents + ) # HARDCODED FOR NOW + data_dict = preprocess_nvgpt(sources, tokenizer, multimodal_cfg) + + elif multimodal_cfg["conv_template"] == "llama_2": + record = { + 'conversations': [{'from': 'human', 'value': prompt,}, {'from': 'gpt', 'value': '',},], + } + + for turn in record['conversations']: + if turn.get('value') is not None: + turn['value'] = re.sub('', f'{DEFAULT_IMAGE_TOKEN}\n', turn['value']) + list_data_dict.append(record) + + sources = preprocess_multimodal( + copy.deepcopy(list_data_dict), multimodal_cfg, num_media_latents + ) # HARDCODED FOR NOW + data_dict = preprocess_llama_2(sources, tokenizer, multimodal_cfg) + elif multimodal_cfg["conv_template"] == "v1": + record = { + 'conversations': [{'from': 'human', 'value': prompt,}, {'from': 'gpt', 'value': '',},], + } + + for turn in record['conversations']: + if turn.get('value') is not None: + turn['value'] = re.sub('', f'{DEFAULT_IMAGE_TOKEN}\n', turn['value']) + list_data_dict.append(record) + + sources = preprocess_multimodal( + copy.deepcopy(list_data_dict), multimodal_cfg, num_media_latents + ) # HARDCODED FOR NOW + data_dict = preprocess_v1(sources, tokenizer, multimodal_cfg) + else: + raise ValueError(f"Conversation template `{conv_template}` is not supported in Neva now.") + return data_dict['tokens'].tolist() + + class NevaModelTextGenerationStrategy(TextGenerationStrategy): def __init__(self, model): super().__init__(model) @@ -335,15 +393,6 @@ def __init__(self, model): self.cfg = self.model.cfg self.data_cfg = self.model.cfg.data - if self.cfg.mm_cfg.vision_encoder.from_hf: - self.processor = CLIPImageProcessor.from_pretrained( - self.cfg.mm_cfg.vision_encoder.from_pretrained, torch_dtype=torch.bfloat16 - ) - else: - self.processor = CLIPImageProcessor.from_pretrained( - "openai/clip-vit-large-patch14", torch_dtype=torch.bfloat16 - ) - add_extra_token = 0 self.multimodal_cfg = dict( is_multimodal=self.data_cfg.is_multimodal, @@ -353,7 +402,7 @@ def __init__(self, model): image_folder=self.data_cfg.image_folder, image_aspect_ratio=self.data_cfg.image_aspect_ratio, use_im_start_end=getattr(self.cfg.mm_cfg, 'use_im_start_end', False), - image_processor=self.processor, + image_processor=None, add_extra_token=add_extra_token, context_length=self.cfg.encoder_seq_length, ) @@ -379,122 +428,36 @@ def init_batch(self, context_tokens: torch.Tensor, context_length: int, compute_ compute_attention_mask=compute_attention_mask, ) - def process_prompts(self, prompt): - from nemo.collections.multimodal.data.neva.neva_dataset import ( - DEFAULT_IMAGE_TOKEN, - preprocess_llama_2, - preprocess_multimodal, - preprocess_nvgpt, - preprocess_v1, - ) - - list_data_dict = [] - if self.multimodal_cfg["conv_template"] == "nvgpt": - record = { - 'system': 'A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user\'s questions.\n\n', - 'conversations': [ - {'from': 'User', 'value': prompt,}, - { - 'from': 'Assistant', - 'value': '', - 'label': 'quality:6,toxicity:0,humor:0,creativity:0,violence:0,helpfulness:6,not_appropriate:0', - }, - ], - } - - for turn in record['conversations']: # - if turn.get('value') is not None: - turn['value'] = re.sub('', f'{DEFAULT_IMAGE_TOKEN}\n', turn['value']) - list_data_dict.append(record) - - sources = preprocess_multimodal( - copy.deepcopy(list_data_dict), self.multimodal_cfg, self.num_media_latents - ) # HARDCODED FOR NOW - data_dict = preprocess_nvgpt(sources, self.tokenizer, self.multimodal_cfg) - - elif self.multimodal_cfg["conv_template"] == "llama_2": - record = { - 'conversations': [{'from': 'human', 'value': prompt,}, {'from': 'gpt', 'value': '',},], - } - - for turn in record['conversations']: - if turn.get('value') is not None: - turn['value'] = re.sub('', f'{DEFAULT_IMAGE_TOKEN}\n', turn['value']) - list_data_dict.append(record) - - sources = preprocess_multimodal( - copy.deepcopy(list_data_dict), self.multimodal_cfg, self.num_media_latents - ) # HARDCODED FOR NOW - data_dict = preprocess_llama_2(sources, self.tokenizer, self.multimodal_cfg) - elif self.multimodal_cfg["conv_template"] == "v1": - record = { - 'conversations': [{'from': 'human', 'value': prompt,}, {'from': 'gpt', 'value': '',},], - } - - for turn in record['conversations']: - if turn.get('value') is not None: - turn['value'] = re.sub('', f'{DEFAULT_IMAGE_TOKEN}\n', turn['value']) - list_data_dict.append(record) + def tokenize_batch(self, prompt, max_len, add_BOS): - sources = preprocess_multimodal( - copy.deepcopy(list_data_dict), self.multimodal_cfg, self.num_media_latents - ) # HARDCODED FOR NOW - data_dict = preprocess_v1(sources, self.tokenizer, self.multimodal_cfg) + if type(prompt) == str: + context_tokens = neva_process_prompts( + prompt, + self.tokenizer, + self.multimodal_cfg, + self.num_media_latents, + self.multimodal_cfg['conv_template'], + ) + elif type(prompt) == list: + context_tokens = [] + for p in prompt: + context_tokens.append( + neva_process_prompts( + p, + self.tokenizer, + self.multimodal_cfg, + self.num_media_latents, + self.multimodal_cfg['conv_template'], + )[0] + ) else: - raise ValueError(f"Conversation template `{self.conv_template}` is not supported in Neva now.") - return data_dict['tokens'].tolist() + raise ValueError(f'{type(prompt)} is not supported for tokenization') - def tokenize_batch(self, prompt, max_len, add_BOS): - context_tokens = self.process_prompts(prompt) context_tokens, context_lengths = pad_batch(context_tokens, self.tokenizer.eos_id, max_len) context_tokens_tensor = torch.cuda.LongTensor(context_tokens) context_length_tensor = torch.cuda.LongTensor(context_lengths) return context_tokens_tensor, context_length_tensor - def get_media_tensor(self, image_path): - from PIL import Image - - image = Image.open(image_path).convert('RGB') - - if self.data_cfg.image_aspect_ratio == 'keep': - max_hw, min_hw = max(image.size), min(image.size) - aspect_ratio = max_hw / min_hw - max_len, min_len = 448, 224 - shortest_edge = int(min(max_len / aspect_ratio, min_len)) - image = self.processor.preprocess( - image, return_tensors='pt', do_center_crop=False, size={"shortest_edge": shortest_edge} - )['pixel_values'][0] - elif self.data_cfg.image_aspect_ratio == 'pad': - - def expand2square(pil_img, background_color): - width, height = pil_img.size - if width == height: - return pil_img - elif width > height: - result = Image.new(pil_img.mode, (width, width), background_color) - result.paste(pil_img, (0, (width - height) // 2)) - return result - else: - result = Image.new(pil_img.mode, (height, height), background_color) - result.paste(pil_img, ((height - width) // 2, 0)) - return result - - image = expand2square(image, tuple(int(x * 255) for x in self.processor.image_mean)) - image = self.processor.preprocess(image, return_tensors='pt')['pixel_values'][0] - else: - image = self.processor.preprocess(image, return_tensors='pt')['pixel_values'][0] - - model_cfg = self.model.cfg - - if model_cfg.precision in [16, '16', '16-mixed']: - media = image.type(torch.float16) - elif model_cfg.precision in [32, '32', '32-true']: - media = image.type(torch.float32) - else: - media = image.type(torch.bfloat16) - - return media.unsqueeze(dim=0).unsqueeze(dim=0).unsqueeze(dim=0) - def prepare_batch_at_step( self, tokens: torch.Tensor, diff --git a/nemo/collections/nlp/modules/common/text_generation_utils.py b/nemo/collections/nlp/modules/common/text_generation_utils.py index 1a13d2278520..38daa44a036a 100644 --- a/nemo/collections/nlp/modules/common/text_generation_utils.py +++ b/nemo/collections/nlp/modules/common/text_generation_utils.py @@ -26,6 +26,11 @@ import torch.nn.functional as F from nemo.collections.common.tokenizers.tabular_tokenizer import TabularTokenizer +from nemo.collections.multimodal.data.neva.conversation import ( + DEFAULT_IM_END_TOKEN, + DEFAULT_IM_START_TOKEN, + DEFAULT_IMAGE_PATCH_TOKEN, +) from nemo.collections.nlp.modules.common.megatron.utils import get_ltor_masks_and_position_ids from nemo.collections.nlp.modules.common.text_generation_strategy import model_inference_strategy_dispatcher from nemo.collections.nlp.modules.common.transformer.text_generation import LengthParam, OutputType, SamplingParam @@ -148,10 +153,9 @@ def megatron_neva_generate(model, prompt_dict_list, length_params, sampling_para conv_template = model.cfg.data.get("conv_template", "nvgpt") final_response = [] for idx, prompt_dict in enumerate(prompt_dict_list): - img = os.path.join(inference_config.inference.images_base_path, prompt_dict['image']) response = generate( model, - inputs=prompt_dict.get("prompt") or prompt_dict.get("text"), + inputs=prompt_dict.get('prompt'), tokens_to_generate=length_params['max_length'], all_probs=sampling_params['all_probs'], compute_logprob=sampling_params['compute_logprob'], @@ -164,17 +168,18 @@ def megatron_neva_generate(model, prompt_dict_list, length_params, sampling_para end_strings=sampling_params['end_strings'], min_tokens_to_generate=length_params['min_length'], compute_attention_mask=sampling_params.get("compute_attention_mask", True), - image_list=img, + image_list=prompt_dict.get('image'), **strategy_args, ) # Regular expression pattern to match the sequence - pattern = re.compile(r'( ⁇ )+') - clean_text = re.sub(pattern, '', response['sentences'][0]) + pattern = re.compile(rf'{DEFAULT_IM_START_TOKEN}( ⁇ )+{DEFAULT_IM_END_TOKEN}') + pattern_nvgpt = re.compile(rf'{DEFAULT_IM_START_TOKEN}({DEFAULT_IMAGE_PATCH_TOKEN})+{DEFAULT_IM_END_TOKEN}') + combined_pattern = re.compile(f'{pattern.pattern}|{pattern_nvgpt.pattern}') + clean_text = re.sub(combined_pattern, '', response['sentences'][0]) clean_response = clean_text - for string in sampling_params['end_strings']: - clean_response = clean_response.rstrip(string) + if conv_template == "nvgpt": labels_str_regexp = re.compile(f"quality:.*\n") last_match_end_position = None @@ -182,9 +187,13 @@ def megatron_neva_generate(model, prompt_dict_list, length_params, sampling_para last_match_end_position = match.end() if last_match_end_position is not None: clean_response = clean_response[last_match_end_position:] + clean_response = clean_response.strip("") elif conv_template == "llama_2": clean_response = clean_response.rsplit("[/INST] ", 1)[-1] - clean_response.strip() + elif conv_template == "v1": + clean_response = clean_response.rsplit("ASSISTANT: ", 1)[-1] + + clean_response = clean_response.strip() response["clean_text"] = clean_text response["clean_response"] = clean_response final_response.append(response) @@ -759,14 +768,10 @@ def sample_sequence_batch( lengths = torch.ones([batch_size]).long().cuda() * maxlen - media_tensor = None - if image_list is not None: - media_tensor = inference_strategy.get_media_tensor(image_list) - while context_length < maxlen: - if media_tensor is not None: + if image_list is not None: batch, tensor_shape = inference_strategy.prepare_batch_at_step( - tokens, maxlen, micro_batch_size, counter, context_length, compute_attention_mask, media_tensor + tokens, maxlen, micro_batch_size, counter, context_length, compute_attention_mask, image_list ) else: batch, tensor_shape = inference_strategy.prepare_batch_at_step( diff --git a/nemo/collections/nlp/parts/nlp_overrides.py b/nemo/collections/nlp/parts/nlp_overrides.py index 6ee36d6983cb..741cb0309813 100644 --- a/nemo/collections/nlp/parts/nlp_overrides.py +++ b/nemo/collections/nlp/parts/nlp_overrides.py @@ -73,6 +73,16 @@ HAVE_APEX = False + +try: + import amp_C + + HAVE_AMP_C = True + +except (ImportError, ModuleNotFoundError): + + HAVE_AMP_C = False + try: from megatron.core import dist_checkpointing, parallel_state from megatron.core.dist_checkpointing.dict_utils import dict_list_map_outplace @@ -930,7 +940,7 @@ def modify_state_dict(self, conf, state_dict): # Modify state key for Dreambooth inference if ( conf.get('target') - == 'nemo.collections.multimodal.models.stable_diffusion.ldm.ddpm.MegatronLatentDiffusion' + == 'nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.ddpm.MegatronLatentDiffusion' ): new_state_dict = {} for key in state_dict.keys(): @@ -1140,7 +1150,13 @@ def __init__( ) self.optimizer_update_skipped: Optional[bool] = None self.hysteresis = hysteresis - self._hysteresis_tracker = self.hysteresis + + def _lazy_init_scale_growth_tracker(self, dev): + super()._lazy_init_scale_growth_tracker(dev) + if HAVE_AMP_C: + self._hysteresis_tracker = torch.tensor([self.hysteresis], dtype=torch.int32, device=dev) + else: + self._hysteresis_tracker = self.hysteresis def _unscale_grads_(self, optimizer, *args): if getattr(optimizer, "_custom_amp_unscale_grads", False): @@ -1150,14 +1166,17 @@ def _unscale_grads_(self, optimizer, *args): def _maybe_opt_step(self, optimizer, optimizer_state, *args, **kwargs): retval = None - found_inf = torch.cuda.FloatTensor([sum(v.item() for v in optimizer_state["found_inf_per_device"].values())]) + found_infs = tuple(optimizer_state["found_inf_per_device"].values()) + found_inf = torch.stack(found_infs).sum(dim=0, keepdim=True) # Update across all model parallel instances. torch.distributed.all_reduce( found_inf, op=torch.distributed.ReduceOp.MAX, group=parallel_state.get_model_parallel_group() ) - if found_inf.item() == 0: + self._found_infs_cpu = found_inf.item() + self._found_infs_cuda = found_inf + if self._found_infs_cpu == 0: retval = optimizer.step(*args, **kwargs) self.optimizer_update_skipped = False else: @@ -1213,11 +1232,38 @@ def update(self, new_scale=None): ) found_inf_combined += found_inf - if found_inf_combined > 0: - self._hysteresis_tracker -= 1 - if self._hysteresis_tracker <= 0: - # When hysteresis becomes zero, follow the native grad scale update rule. - # Increase scale and reset growth tracker + if HAVE_AMP_C: + amp_C.update_scale_hysteresis( + _scale, + _growth_tracker, + self._hysteresis_tracker, + found_inf_combined, + self._growth_factor, + self._backoff_factor, + self._growth_interval, + self.hysteresis, + ) + else: + if found_inf_combined > 0: + self._hysteresis_tracker -= 1 + if self._hysteresis_tracker <= 0: + # When hysteresis becomes zero, follow the native grad scale update rule. + # Increase scale and reset growth tracker + torch._amp_update_scale_( + _scale, + _growth_tracker, + found_inf_combined, + self._growth_factor, + self._backoff_factor, + self._growth_interval, + ) + else: + # Only reset the growth tracker when hysteresis is larger than zero + _growth_tracker.fill_(0.0) + else: + # When no inf found, follow the native grad scale update rule. + # Increment growth_tracker, update scale when growth tracker reaches the interval, and + # reset the hysteresis tracker. torch._amp_update_scale_( _scale, _growth_tracker, @@ -1226,22 +1272,7 @@ def update(self, new_scale=None): self._backoff_factor, self._growth_interval, ) - else: - # Only reset the growth tracker when hysteresis is larger than zero - _growth_tracker.fill_(0.0) - else: - # When no inf found, follow the native grad scale update rule. - # Increment growth_tracker, update scale when growth tracker reaches the interval, and - # reset the hysteresis tracker. - torch._amp_update_scale_( - _scale, - _growth_tracker, - found_inf_combined, - self._growth_factor, - self._backoff_factor, - self._growth_interval, - ) - self._hysteresis_tracker = self.hysteresis + self._hysteresis_tracker = self.hysteresis # To prepare for next iteration, clear the data collected from optimizers this iteration. self._per_optimizer_states = defaultdict(torch.cuda.amp.grad_scaler._refresh_per_optimizer_state) @@ -1288,7 +1319,10 @@ def load_state_dict(self, state_dict): if "_hysterisis_tracker" in state_dict: self._hysteresis_tracker = state_dict["_hysterisis_tracker"] else: - self._hysteresis_tracker = 1 + if HAVE_AMP_C: + self._hysteresis_tracker = torch.tensor([1], dtype=torch.int32, device="cuda") + else: + self._hysteresis_tracker = 1 class MegatronHalfPrecisionPlugin(MixedPrecisionPlugin): diff --git a/nemo/collections/nlp/parts/peft_config.py b/nemo/collections/nlp/parts/peft_config.py index c01ba337e8c2..72bcdf55e8ae 100644 --- a/nemo/collections/nlp/parts/peft_config.py +++ b/nemo/collections/nlp/parts/peft_config.py @@ -199,6 +199,30 @@ def __init__(self, cfg): super().__init__(adapter_tuning_cfg, name_key_to_cfg) +class SDLoraPEFTConfig(PEFTConfig): + def __init__(self, cfg): + lora_cfg = cfg.peft.lora_tuning + + # Stable diffusion has different attn dimensions, we pass a dummy config and infer from each module when adding adapter + config_args = { + "in_features": None, + "out_features": None, + "dim": lora_cfg.adapter_dim, + "norm_position": None, + "norm_type": None, + "activation": "identity", + "column_init_method": lora_cfg.get("column_init_method", "normal"), + "row_init_method": lora_cfg.get("row_init_method", "zero"), + "gather_output": False, + "dropout": lora_cfg.adapter_dropout, + "network_alpha": lora_cfg.network_alpha, + } + + name_key_to_cfg = {AdapterName.PARALLEL_LINEAR_ADAPTER: ParallelLinearAdapterConfig(**config_args)} + self.name_key_to_mcore_mixins = None + super().__init__(lora_cfg, name_key_to_cfg) + + PEFT_CONFIG_MAP = { "adapter": CanonicalAdaptersPEFTConfig, "ia3": IA3PEFTConfig, @@ -207,4 +231,5 @@ def __init__(self, cfg): "selective": SelectivePEFTConfig, 'none': None, None: None, + "sdlora": SDLoraPEFTConfig, } diff --git a/nemo/collections/vision/modules/common/megatron/vision_transformer.py b/nemo/collections/vision/modules/common/megatron/vision_transformer.py index 744c821f984a..80793067128c 100644 --- a/nemo/collections/vision/modules/common/megatron/vision_transformer.py +++ b/nemo/collections/vision/modules/common/megatron/vision_transformer.py @@ -36,7 +36,7 @@ ModelType = AttnMaskType = AttnType = LayerType = ApexGuardDefaults() try: - from megatron.core import parallel_state + from megatron.core import ModelParallelConfig, parallel_state HAVE_MEGATRON_CORE = True @@ -82,6 +82,16 @@ def forward(self, hidden_state): return output +class LayerScale(torch.nn.Module): + def __init__(self, dim, init_values=1e-5, inplace=False): + super().__init__() + self.inplace = inplace + self.gamma = torch.nn.Parameter(init_values * torch.ones(dim)) + + def forward(self, x): + return x.mul_(self.gamma) if self.inplace else x * self.gamma + + class ParallelVisionTransformerLayer_(ParallelTransformerLayer_): """A single transformer layer. @@ -91,7 +101,7 @@ class ParallelVisionTransformerLayer_(ParallelTransformerLayer_): def __init__( self, - config, + config: ModelParallelConfig, init_method, output_layer_init_method, layer_number, @@ -102,37 +112,48 @@ def __init__( self_attn_mask_type=AttnMaskType.padding, fp32_residual_connection=False, precision=16, - apply_query_key_layer_scaling=True, + apply_query_key_layer_scaling=False, kv_channels=None, layernorm_epsilon=1e-5, hidden_dropout=0.1, - bias_dropout_add_fusion=True, persist_layer_norm=False, bias_activation_fusion=True, + bias_dropout_add_fusion=True, + masked_softmax_fusion=True, openai_gelu=False, onnx_safe=False, - masked_softmax_fusion=True, attention_dropout=0.1, ffn_dropout=0.0, drop_path_rate=0.0, + layerscale=False, activation='gelu', megatron_legacy=False, bias=True, chunk_size=64, normalization='layernorm', transformer_block_type='pre_ln', + position_embedding_type='learned_absolute', + multi_query_attention=False, headscale=False, activations_checkpoint_granularity=None, normalize_attention_scores=True, + num_moe_experts=1, + moe_frequency=1, + moe_dropout=0.0, use_flash_attention=False, ): kwargs = locals() for key in ["self", "__class__"]: kwargs.pop(key) drop_path_rate = kwargs.pop("drop_path_rate") + layerscale = kwargs.pop("layerscale") super(ParallelVisionTransformerLayer_, self).__init__(**kwargs) self.drop_path = DropPath(drop_path_rate) if drop_path_rate > 0.0 else None + self.layerscale = layerscale + if self.layerscale: + self.post_attention_layerscale = LayerScale(hidden_size, init_values=1e-5) + self.post_mlp_layerscale = LayerScale(hidden_size, init_values=1e-5) def forward( self, @@ -144,8 +165,7 @@ def forward( get_key_value=False, set_inference_key_value_memory=False, inference_max_sequence_len=None, - rotary_pos_emb=None, - # list of positional embedding tensors, first one self attention, second one and third one are for cross attention (q, k) + rotary_pos_emb=None, # list of positional embedding tensors, first one self attention, second one and third one are for cross attention (q, k) self_attention_relative_position_bias=None, cross_attention_relative_position_bias=None, checkpoint_core_attention=False, @@ -200,7 +220,14 @@ def forward( # different nn.functional routines to account for varying # dropout semantics during training and inference phases. - if self.drop_path is None: + if self.is_adapter_available(): + adapter_1 = self.get_adapter_module(AdapterName.PRE_ATTN_ADAPTER) + if adapter_1: + attention_output = ( + adapter_1(attention_output) + attention_output + ) # simple adapter call with residual connection + + if self.drop_path is None and not self.layerscale: bias_dropout_add_func = self._get_bias_droput_add_func( transformer_block_type=self.transformer_block_type, position_after='attention' ) @@ -215,8 +242,11 @@ def forward( out = torch.nn.functional.dropout( attention_output + attention_bias, p=self.hidden_dropout, training=self.training ) - layernorm_input = residual + self.drop_path(out) - # print(f"Layer: {self.layer_number} Attention checksum {layernorm_input.sum()}") + if self.drop_path is not None: + out = self.drop_path(out) + if self.layerscale: + out = self.post_attention_layerscale(out) + layernorm_input = residual + out # Post-LN normalization after residual if self.transformer_block_type == 'post_ln': @@ -283,10 +313,15 @@ def forward( layernorm_input = normalization_output # MLP. mlp_output, mlp_bias = self.mlp(normalization_output) + if self.is_adapter_available(): + # TODO: (@adithyre) was able to move adapter_2 back to the end of the transformer after ptl 1.7 update. + adapter_2 = self.get_adapter_module(AdapterName.POST_ATTN_ADAPTER) + if adapter_2: + mlp_output = adapter_2(mlp_output) + mlp_output # simple adapter call with residual connection residual = layernorm_input - if self.drop_path is None: + if self.drop_path is None and not self.layerscale: bias_dropout_add_func = self._get_bias_droput_add_func( transformer_block_type=self.transformer_block_type, position_after='mlp' ) @@ -295,7 +330,11 @@ def forward( else: out = torch.nn.functional.dropout(mlp_output + mlp_bias, p=self.hidden_dropout, training=self.training) - output = residual + self.drop_path(out) + if self.drop_path is not None: + out = self.drop_path(out) + if self.layerscale: + out = self.post_mlp_layerscale(out) + output = residual + out # print(f"Layer: {self.layer_number} MLP + Dropout + Residual checksum {output.sum()}") if self.transformer_block_type == 'post_ln': @@ -349,14 +388,14 @@ class ParallelVisionTransformer(ParallelTransformer): def __init__( self, - config, + config: ModelParallelConfig, init_method, output_layer_init_method, num_layers, hidden_size, ffn_hidden_size, num_attention_heads, - apply_query_key_layer_scaling=True, + apply_query_key_layer_scaling=False, kv_channels=None, layer_type=LayerType.encoder, # it can be a list of types or single type self_attn_mask_type=AttnMaskType.padding, @@ -371,6 +410,7 @@ def __init__( attention_dropout=0.1, ffn_dropout=0.0, drop_path_rate=0.0, + layerscale=False, bias_activation_fusion=True, bias_dropout_add_fusion=True, masked_softmax_fusion=True, @@ -384,17 +424,34 @@ def __init__( chunk_size=64, normalization='layernorm', transformer_block_type='pre_ln', + position_embedding_type='learned_absolute', headscale=False, layer_number_offset=0, # this is use only for attention norm_factor scaling activations_checkpoint_granularity=None, - normalize_attention_scores=True, + activations_checkpoint_layers_per_pipeline=None, + transformer_engine=False, + fp8=False, + fp8_e4m3=False, + fp8_hybrid=False, + fp8_margin=0, + fp8_interval=1, + fp8_amax_history_len=1, + fp8_amax_compute_algo='most_recent', + reduce_amax=True, + use_emha=False, ub_tp_comm_overlap=False, + normalize_attention_scores=True, + multi_query_attention=False, + num_moe_experts=1, + moe_frequency=1, + moe_dropout=0.0, use_flash_attention=False, ): kwargs = locals() for key in ["self", "__class__"]: kwargs.pop(key) self.drop_path_rate = kwargs.pop("drop_path_rate") + layerscale = kwargs.pop("layerscale") super(ParallelVisionTransformer, self).__init__(**kwargs) self.num_layers = self.get_num_layers(num_layers) @@ -431,10 +488,12 @@ def build_layer(layer_number): attention_dropout=attention_dropout, ffn_dropout=ffn_dropout, drop_path_rate=self.drop_path_rates[layer_number - 1], + layerscale=layerscale, bias_activation_fusion=bias_activation_fusion, bias_dropout_add_fusion=bias_dropout_add_fusion, masked_softmax_fusion=masked_softmax_fusion, persist_layer_norm=persist_layer_norm, + position_embedding_type=position_embedding_type, openai_gelu=openai_gelu, onnx_safe=onnx_safe, activation=activation, @@ -446,6 +505,9 @@ def build_layer(layer_number): headscale=headscale, activations_checkpoint_granularity=activations_checkpoint_granularity, normalize_attention_scores=normalize_attention_scores, + num_moe_experts=num_moe_experts, + moe_frequency=moe_frequency, + moe_dropout=moe_dropout, use_flash_attention=use_flash_attention, ) diff --git a/nemo/collections/vision/modules/vit/vit_backbone.py b/nemo/collections/vision/modules/vit/vit_backbone.py index 422ccf65475e..ebd7e0da3e5c 100644 --- a/nemo/collections/vision/modules/vit/vit_backbone.py +++ b/nemo/collections/vision/modules/vit/vit_backbone.py @@ -213,8 +213,8 @@ def __init__( self.num_patches_per_dim_h = self.img_h // self.patch_dim self.num_patches_per_dim_w = self.img_w // self.patch_dim self.num_patches = self.num_patches_per_dim_h * self.num_patches_per_dim_w - class_token_length = model_cfg.get("class_token_length", 8) - self.seq_length = self.num_patches + (class_token_length if self.class_token else 0) + self.class_token_length = model_cfg.get("class_token_length", 8) if self.class_token else 0 + self.seq_length = self.num_patches + self.class_token_length self.flatten_dim = self.patch_dim * self.patch_dim * model_cfg.num_channels self.input_tensor = None self.position_ids = None @@ -223,7 +223,7 @@ def __init__( if self.pre_process: # cls_token if self.class_token: - self.cls_token = torch.nn.Parameter(torch.randn(1, class_token_length, self.hidden_size)) + self.cls_token = torch.nn.Parameter(torch.randn(1, self.class_token_length, self.hidden_size)) torch.nn.init.zeros_(self.cls_token) self.position_ids = torch.arange(self.seq_length).expand(1, -1).cuda() @@ -249,7 +249,7 @@ def __init__( self.embedding_dropout = torch.nn.Dropout(model_cfg.hidden_dropout) self.drop_patch = DropPatch( - self.drop_patch_rate, class_token_length=class_token_length, exclude_cls_tokens=self.class_token + self.drop_patch_rate, class_token_length=self.class_token_length, exclude_cls_tokens=self.class_token ) if preprocess_layernorm: @@ -282,6 +282,7 @@ def __init__( hidden_dropout=model_cfg.hidden_dropout, attention_dropout=model_cfg.attention_dropout, drop_path_rate=model_cfg.drop_path_rate, + layerscale=model_cfg.get("layerscale", False), bias_activation_fusion=model_cfg.get("bias_activation_fusion", False), persist_layer_norm=model_cfg.persist_layer_norm, openai_gelu=model_cfg.openai_gelu, @@ -298,6 +299,36 @@ def set_input_tensor(self, input_tensor): """See megatron.model.transformer.set_input_tensor()""" self.transformer.set_input_tensor(input_tensor) + def interpolate_pos_encoding( + self, x, + ): + output_seq_len = x.shape[1] + assert isPerfectSquare(output_seq_len - self.class_token_length) + + num_tok_output = output_seq_len - self.class_token_length + num_tok_input = self.num_patches + + if num_tok_input == num_tok_output: + return self.position_embeddings + + embed_tok = self.position_embeddings[: self.class_token_length] + embed_grid = self.position_embeddings[self.class_token_length :] + + gs_new = int(math.sqrt(num_tok_output)) + gs_input = (self.num_patches_per_dim_h, self.num_patches_per_dim_w) + + embed_grid = embed_grid.transpose(0, 1).contiguous() + embed_grid = embed_grid.reshape((1, -1, gs_input[0], gs_input[1])) + embed_grid = embed_grid.float() + scale_factor = (gs_new / gs_input[0], gs_new / gs_input[1]) + + embed_grid = F.interpolate(embed_grid, scale_factor=scale_factor, mode="bicubic") + + embed_grid = embed_grid.reshape((-1, num_tok_output)) + embed_grid = embed_grid.transpose(0, 1).contiguous() + + return torch.cat((embed_tok, embed_grid), dim=0) + def forward(self, input): if self.pre_process: @@ -318,7 +349,7 @@ def forward(self, input): self.position_ids[:, : concatenated_tokens.shape[1]] ) elif self.position_embedding_type == "learned_parameters": - token_embeddings = concatenated_tokens + self.position_embeddings + token_embeddings = concatenated_tokens + self.interpolate_pos_encoding(concatenated_tokens) else: raise ValueError(f"Unrecognized position embedding type: {self.position_embedding_type}.") diff --git a/nemo/utils/callbacks/__init__.py b/nemo/utils/callbacks/__init__.py index 6623657a2dc2..6992ce751ed5 100644 --- a/nemo/utils/callbacks/__init__.py +++ b/nemo/utils/callbacks/__init__.py @@ -12,5 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. +from nemo.utils.callbacks.cuda_graph import CUDAGraphCallback from nemo.utils.callbacks.nemo_model_checkpoint import NeMoModelCheckpoint from nemo.utils.callbacks.preemption import PreemptionCallback diff --git a/nemo/utils/callbacks/cuda_graph.py b/nemo/utils/callbacks/cuda_graph.py new file mode 100644 index 000000000000..ba6046b79850 --- /dev/null +++ b/nemo/utils/callbacks/cuda_graph.py @@ -0,0 +1,385 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. 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 os +import time +from dataclasses import dataclass +from types import MethodType +from typing import Any, Dict + +import pytorch_lightning as pl +import torch +from pytorch_lightning.callbacks import Callback +from pytorch_lightning.loops.optimization.automatic import ClosureResult +from pytorch_lightning.utilities.rank_zero import rank_zero_info +from pytorch_lightning.utilities.signature_utils import is_param_in_hook_signature +from pytorch_lightning.utilities.types import STEP_OUTPUT +from torch.nn.parallel import DistributedDataParallel + +__all__ = ["CUDAGraphCallback"] + + +def struct_copy_one(src): + if isinstance(src, tuple): + return tuple(struct_copy_one(i) for i in src) + elif isinstance(src, list): + return list(struct_copy_one(i) for i in src) + elif isinstance(src, dict): + return {k: struct_copy_one(src[k]) for k in src} + elif isinstance(src, torch.Tensor): + return src.clone().detach().cuda() + else: + return src + + +def struct_copy_two(tgt, src): + if isinstance(src, tuple): + raise Exception(f"Unsupported copy for tuple yet: {type(src)}") + elif isinstance(src, list): + for i in range(len(src)): + if isinstance(src[i], (tuple, list, dict, torch.Tensor)): + struct_copy_two(tgt[i], src[i]) + else: + tgt[i] = src[i] + elif isinstance(src, dict): + for k in src: + if isinstance(src[k], (tuple, list, dict, torch.Tensor)): + struct_copy_two(tgt[k], src[k]) + else: + tgt[k] = src[k] + elif isinstance(src, torch.Tensor): + tgt.copy_(src, non_blocking=True) + else: + raise Exception(f"Expect top-level as container type but got: {type(src)}") + + +class StaticBufferLoader: + """Load data to static buffers.""" + + def __init__(self, loader): + self.loader = loader + self.stream = torch.cuda.Stream() + self.static = None + + def __iter__(self): + for inputs in self.loader: + if self.static is None: + with torch.cuda.stream(self.stream): + self.static = struct_copy_one(inputs) + + with torch.cuda.stream(self.stream): + struct_copy_two(self.static, inputs) + torch.cuda.current_stream().wait_stream(self.stream) + yield self.static + + def __len__(self): + return len(self.loader) + + +def get_lr(lr_scheduler): + lrs = lr_scheduler.__orig_get_lr__() + if not hasattr(lr_scheduler, "static_lrs"): + lr_scheduler.static_lrs = lrs + for i in range(len(lrs)): + lr_scheduler.static_lrs[i].copy_(lrs[i]) + return lr_scheduler.static_lrs + + +def zero_grad(optimizer, *args, **kwargs): + # We invoke zero_grad before graph capturing. + if torch.cuda.is_current_stream_capturing(): + rank_zero_info("CUDAGraphCallback: set optimizer.zero_grad as nop during graph capturing.") + else: + optimizer.__orig_zero_grad__(*args, **kwargs) + + +def get_optimizer_step(state): + def optimizer_step(self, epoch, batch_idx, optimizer, optimizer_closure=None,) -> None: + # Not all optimizer supports set_to_none. + if not hasattr(optimizer, "support_set_to_none"): + optimizer.support_set_to_none = is_param_in_hook_signature( + optimizer.zero_grad, "set_to_none", explicit=True + ) + if optimizer.support_set_to_none: + zero_grad_kwargs = {"set_to_none": True} + else: + zero_grad_kwargs = {} + + if 0 <= state.current_iteration < state.capture_iteration or state.capture_iteration < 0: + state.stream.wait_stream(torch.cuda.current_stream()) + with torch.cuda.stream(state.stream): + optimizer.zero_grad(**zero_grad_kwargs) + self.__orig_optimizer_step__( + epoch, batch_idx, optimizer, optimizer_closure=optimizer_closure, + ) + torch.cuda.current_stream().wait_stream(state.stream) + + if state.current_iteration == state.capture_iteration: + optimizer.zero_grad(**zero_grad_kwargs) + torch.cuda.synchronize() + # Sleep for one second to let environment stable + time.sleep(1) + rank_zero_info("CUDAGraphCallback: capturing CUDA graph for module %s.", self.__class__.__name__) + with torch.cuda.graph(state.graph, stream=state.stream): + self.__orig_optimizer_step__( + epoch, batch_idx, optimizer, optimizer_closure=optimizer_closure, + ) + torch.cuda.synchronize() + + # Graph replay and reconstruct missing result + if state.current_iteration >= state.capture_iteration >= 0: + state.graph.replay() + optimizer_closure._result = ClosureResult.from_training_step_output(state.output) + + # If something is not capturable, try to put it there, e.g. `self.log()`. + if hasattr(self, "non_cuda_graph_capturable"): + self.non_cuda_graph_capturable() + + state.current_iteration += 1 + + return optimizer_step + + +def get_training_step(state): + def training_step(self, batch, batch_idx): + results = self.__orig_training_step__(batch, batch_idx) + if state.output is None: + state.output = struct_copy_one(results) + + # Copy results to static buffer to rebuild states required by PL. + with torch.no_grad(): + struct_copy_two(state.output, results) + return results + + return training_step + + +def get_amp_autocast_init(state): + def amp_autocast_init(self, *args, **kwargs): + if "cache_enabled" not in kwargs: + kwargs["cache_enabled"] = False + if state.current_iteration == 0: + rank_zero_info("CUDAGraphCallback: disable autocast cache.") + return self.__orig_init__(*args, **kwargs) + + return amp_autocast_init + + +def get_ddp_init(state): + def init(self, *args, **kwargs): + rank_zero_info("CUDAGraphCallback: init DDP on side stream.") + with torch.cuda.stream(state.stream): + self.__orig_init__(*args, **kwargs) + + return init + + +@dataclass +class CUDAGraphState: + current_iteration: int = 0 + capture_iteration: int = -1 # -1 to disable + stream: torch.cuda.Stream = None + graph: torch.cuda.CUDAGraph = None + output: Any = None # static forward output + + +class CUDAGraphCallback(Callback): + """Full iteration CUDA graph callback. + + Dataloader and LR scheduler are not included in the CUDA graph with this callback. + """ + + def __init__(self, capture_iteration=-1): + super().__init__() + + # Required by CUDA graph with DDP + # Ref: https://pytorch.org/docs/stable/notes/cuda.html#usage-with-distributeddataparallel + if 0 <= capture_iteration <= 11: + raise Exception("Warmup must run at least 11 DDP-enabled eager iterations before capture.") + if torch.distributed.is_initialized(): + raise Exception("CUDAGraphCallback should be initialized before process group.") + os.environ["NCCL_ASYNC_ERROR_HANDLING"] = "0" + + self.state = CUDAGraphState(capture_iteration=capture_iteration) + + def setup(self, trainer: "pl.Trainer", pl_module: "pl.LightningModule", stage: str) -> None: + """Called when fit, validate, test, predict, or tune begins.""" + if self.state.capture_iteration < 0: + return + + # Hack to avoid CUDA graph issue with AMP, PyTorch Lightning doesn't support + # changing autocast arguments for now. + # https://github.com/pytorch/pytorch/blob/v1.13.1/torch/cuda/graphs.py#L234 + torch.autocast.__orig_init__ = torch.autocast.__init__ + torch.autocast.__init__ = get_amp_autocast_init(self.state) + + # Before full-backward capture, DDP must be constructed in a side-stream context. + # We've merged the change that init DDP on side stream to PyTorch Lightning V2, + # but not all user defined strategy init DDP on side stream. + DistributedDataParallel.__orig_init__ = DistributedDataParallel.__init__ + DistributedDataParallel.__init__ = get_ddp_init(self.state) + + def teardown(self, trainer: "pl.Trainer", pl_module: "pl.LightningModule", stage: str) -> None: + """Called when fit, validate, test, predict, or tune ends.""" + if self.state.capture_iteration < 0: + return + + torch.autocast.__init__ = torch.autocast.__orig_init__ + del torch.autocast.__orig_init__ + + DistributedDataParallel.__init__ = DistributedDataParallel.__orig_init__ + del DistributedDataParallel.__orig_init__ + + def on_fit_start(self, trainer: "pl.Trainer", pl_module: "pl.LightningModule") -> None: + """Called when fit begins.""" + if self.state.capture_iteration < 0: + return + + if is_param_in_hook_signature(pl_module, "dataloader_iter", explicit=True): + raise Exception( + "Found `dataloader_iter` argument in the `training_step`. This is " + "not supported by full iteration CUDA graph capturing yet since " + "dataloader will be within the CUDA graph capturing range.\n" + "Try to change `dataloader_iter` to `batch` and remove " + "`next(dataloader_iter)` from `training_step`." + ) + + # Now that CUDA device has been set, we can init stream and graph now + self.state.stream = torch.cuda.Stream() + self.state.graph = torch.cuda.CUDAGraph() + + def on_fit_end(self, trainer: "pl.Trainer", pl_module: "pl.LightningModule") -> None: + """Called when fit ends.""" + if self.state.capture_iteration < 0: + return + + def on_train_start(self, trainer: "pl.Trainer", pl_module: "pl.LightningModule") -> None: + """Called when the train begins.""" + if self.state.capture_iteration < 0: + return + + # Ensure training dataloader loads data to static buffer + dataloader = trainer.train_dataloader + assert isinstance( + dataloader, torch.utils.data.dataloader.DataLoader + ), f"Expect Dataloader type but got {type(dataloader)}" + trainer.train_dataloader.__orig_dataloader__ = dataloader + static_loader = StaticBufferLoader(dataloader) + trainer.train_dataloader.loaders = static_loader + + # Warn if `optimizer.zero_grad()` invoked during graph capturing + for optimizer in trainer.optimizers: + assert isinstance(optimizer, torch.optim.Optimizer), f"Expect Optimizer type but got {type(optimizer)}" + optimizer.__orig_zero_grad__ = optimizer.zero_grad + optimizer.zero_grad = MethodType(zero_grad, optimizer) + + # Ensure LR scheduler writes to static buffer + # We don't include LR scheduler in the full CUDA graph for now since + # its overhead is very small. + for config in trainer.lr_scheduler_configs: + assert isinstance( + config.scheduler, torch.optim.lr_scheduler._LRScheduler + ), f"Expect _LRScheduler type but got {type(dataloader)}" + config.scheduler.__orig_get_lr__ = config.scheduler.get_lr + config.scheduler.get_lr = MethodType(get_lr, config.scheduler) + + # Save model outputs to static buffer for PL states reconstruct + pl_module.__orig_training_step__ = pl_module.training_step + training_step = get_training_step(self.state) + pl_module.training_step = MethodType(training_step, pl_module) + + # Capture CUDA graph from model forward propagation to optimizer step + pl_module.__orig_optimizer_step__ = pl_module.optimizer_step + optimizer_step = get_optimizer_step(self.state) + pl_module.optimizer_step = MethodType(optimizer_step, pl_module) + + def on_train_end(self, trainer: "pl.Trainer", pl_module: "pl.LightningModule") -> None: + """Called when the train ends.""" + if self.state.capture_iteration < 0: + return + + dataloader = trainer.train_dataloader.__orig_dataloader__ + trainer.train_dataloader.loaders = dataloader + del trainer.train_dataloader.__orig_dataloader__ + + for optimizer in trainer.optimizers: + optimizer.zero_grad = optimizer.__orig_zero_grad__ + del optimizer.__orig_zero_grad__ + + for config in trainer.lr_scheduler_configs: + config.scheduler.get_lr = config.scheduler.__orig_get_lr__ + del config.scheduler.__orig_get_lr__ + + pl_module.training_step = pl_module.__orig_training_step__ + del pl_module.__orig_training_step__ + + pl_module.optimizer_step = pl_module.__orig_optimizer_step__ + del pl_module.__orig_optimizer_step__ + + def on_train_epoch_start(self, trainer: "pl.Trainer", pl_module: "pl.LightningModule") -> None: + """Called when the train epoch begins.""" + pass + + def on_train_epoch_end(self, trainer: "pl.Trainer", pl_module: "pl.LightningModule") -> None: + """Called when the train epoch ends. + + To access all batch outputs at the end of the epoch, either: + + 1. Implement `training_epoch_end` in the `LightningModule` and access outputs via the module OR + 2. Cache data across train batch hooks inside the callback implementation to post-process in this hook. + """ + pass + + def on_train_batch_start( + self, trainer: "pl.Trainer", pl_module: "pl.LightningModule", batch: Any, batch_idx: int + ) -> None: + """Called when the train batch begins.""" + pass + + def on_train_batch_end( + self, trainer: "pl.Trainer", pl_module: "pl.LightningModule", outputs: STEP_OUTPUT, batch: Any, batch_idx: int + ) -> None: + """Called when the train batch ends. + + Note: + The value ``outputs["loss"]`` here will be the normalized value w.r.t ``accumulate_grad_batches`` of the + loss returned from ``training_step``. + """ + pass + + def on_save_checkpoint( + self, trainer: "pl.Trainer", pl_module: "pl.LightningModule", checkpoint: Dict[str, Any] + ) -> None: + r""" + Called when saving a checkpoint to give you a chance to store anything else you might want to save. + + Args: + trainer: the current :class:`~pytorch_lightning.trainer.Trainer` instance. + pl_module: the current :class:`~pytorch_lightning.core.module.LightningModule` instance. + checkpoint: the checkpoint dictionary that will be saved. + """ + # Since we've add bound method to optimizer and lr_scheduler, it can lead to more + # CUDA tensors passed to consumer process unexpectedly. + if "optimizer_states" in checkpoint: + for optimizer_state in checkpoint["optimizer_states"]: + for k in list(optimizer_state.keys()): + v = optimizer_state[k] + if isinstance(v, MethodType) and hasattr(v, "__self__"): + del optimizer_state[k] + if "lr_schedulers" in checkpoint: + for lr_scheduler in checkpoint["lr_schedulers"]: + for k in list(lr_scheduler.keys()): + v = lr_scheduler[k] + if isinstance(v, MethodType) and hasattr(v, "__self__"): + del lr_scheduler[k] diff --git a/requirements/requirements_docs.txt b/requirements/requirements_docs.txt index 34406bd2a366..8412c67d4ab2 100644 --- a/requirements/requirements_docs.txt +++ b/requirements/requirements_docs.txt @@ -1,3 +1,4 @@ +boto3 Jinja2<3.1 latexcodec numpy diff --git a/scripts/diffusion_model_lora_merge/conf/merge_lora_weights.yaml b/scripts/diffusion_model_lora_merge/conf/merge_lora_weights.yaml new file mode 100644 index 000000000000..b13bfc68cd6d --- /dev/null +++ b/scripts/diffusion_model_lora_merge/conf/merge_lora_weights.yaml @@ -0,0 +1,16 @@ +name: stable-diffusion-train + +trainer: + devices: 1 + num_nodes: 1 + accelerator: gpu + precision: 16 + logger: False # logger provided by exp_manager + +model: + restore_from_path: null + precision: ${trainer.precision} + +lora_model_path: null +lora_scale: 1.0 +merged_model_path: null \ No newline at end of file diff --git a/scripts/diffusion_model_lora_merge/merge_lora_weights_into_base_model.py b/scripts/diffusion_model_lora_merge/merge_lora_weights_into_base_model.py new file mode 100644 index 000000000000..57d9964cad3d --- /dev/null +++ b/scripts/diffusion_model_lora_merge/merge_lora_weights_into_base_model.py @@ -0,0 +1,85 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. 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 tempfile +from typing import Any, Dict + +import torch +from pytorch_lightning import Trainer + +from nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.ddpm import MegatronLatentDiffusion +from nemo.collections.multimodal.parts.utils import setup_trainer_and_model_for_inference +from nemo.collections.nlp.parts.nlp_overrides import NLPDDPStrategy, NLPSaveRestoreConnector +from nemo.core.config import hydra_runner + + +def load_lora(lora_nemo): + + with tempfile.TemporaryDirectory() as tmpdir: + NLPSaveRestoreConnector._unpack_nemo_file(lora_nemo, tmpdir) + # assert os.path.isdir(lora_extracted_dir), "requires the untar'ed the lora .nemo file" + + ckpt_file = f"{tmpdir}/model_weights.ckpt" + + lora_state_dict = torch.load(ckpt_file, map_location=torch.device('cpu')) + return lora_state_dict + + +def merge(base_model_state_dict: Dict[str, Any], lora_state_dict: Dict[int, Any], lora_scale=1.0): + + for key in lora_state_dict.keys(): + if 'linear_out' in key: + continue + key_lora_in = key + key_lora_out = key.replace('linear_in', 'linear_out') + key_base_model = key.replace('.adapter_layer.parallel_linear_adapter.linear_in', '').replace('._orig_mod', '') + + wt_lora_in = lora_state_dict[key_lora_in] + wt_lora_out = lora_state_dict[key_lora_out] + wt_base_model = base_model_state_dict[key_base_model] + + wt_lora = wt_lora_out @ wt_lora_in + base_model_state_dict[key_base_model] = wt_base_model + wt_lora * lora_scale + print(f"merging weights for following key : {key_base_model}") + return base_model_state_dict + + +@hydra_runner(config_path="conf", config_name="merge_lora_weights") +def main(cfg) -> None: + trainer = Trainer(strategy=NLPDDPStrategy(), **cfg.trainer) + + def model_cfg_modifier(model_cfg): + model_cfg.precision = cfg.trainer.precision + model_cfg.ckpt_path = None + model_cfg.inductor = False + model_cfg.unet_config.use_flash_attention = False + model_cfg.unet_config.from_pretrained = None + model_cfg.first_stage_config.from_pretrained = None + + trainer, megatron_diffusion_model = setup_trainer_and_model_for_inference( + model_provider=MegatronLatentDiffusion, cfg=cfg, model_cfg_modifier=model_cfg_modifier + ) + model = megatron_diffusion_model.cpu() + lora_weights = load_lora(cfg.lora_model_path) + + merged_weights = merge(model.state_dict(), lora_weights, lora_scale=cfg.lora_scale) + + model.load_state_dict(merged_weights) + + model.save_to(cfg.merged_model_path) + print(f"saved merged model to {cfg.merged_model_path}") + + +if __name__ == '__main__': + main() diff --git a/scripts/fid-eval-text2img/compute_clip_score.py b/scripts/fid-eval-text2img/compute_clip_score.py new file mode 100644 index 000000000000..ab573f76c67f --- /dev/null +++ b/scripts/fid-eval-text2img/compute_clip_score.py @@ -0,0 +1,149 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. 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. + +""" +python clip_script.py --captions_path /path/to/coco2014_val/captions \ + --fid_images_path /path/to/synthetic_images \ + --output_path /path/to/output/clip_scores.csv + +1. `--captions_path`: The path to the real images captions directory. In this example, + it is set to `/path/to/coco2014_val/captions`. This path should point to the + directory containing the COCO 2014 validation dataset captions. + +2. `--fid_images_path`: The path to the directory containing subfolders with synthetic + images. In this example, it is set to `/path/to/synthetic_images`. Each subfolder + should contain a set of synthetic images for which you want to compute CLIP scores + against the captions from `--captions_path`. + +3. `--output_path`: The path to the output CSV file where the CLIP scores will be saved. + In this example, it is set to `/path/to/output/clip_scores.csv`. This file will + contain a table with two columns: `cfg` and `clip_score`. The `cfg` + column lists the names of the subfolders in `--fid_images_path`, and the + `clip_score` column lists the corresponding average CLIP scores between the synthetic + images in each subfolder and the captions from `--captions_path`. +""" + +import argparse +import csv +import os +from glob import glob + +import open_clip +import torch +import torch.nn as nn +from PIL import Image +from tqdm import tqdm + + +class CLIPEncoder(nn.Module): + def __init__(self, clip_version='ViT-B/32', pretrained='', cache_dir=None, device='cuda'): + super().__init__() + + self.clip_version = clip_version + if not pretrained: + if self.clip_version == 'ViT-H-14': + self.pretrained = 'laion2b_s32b_b79k' + elif self.clip_version == 'ViT-g-14': + self.pretrained = 'laion2b_s12b_b42k' + else: + self.pretrained = 'openai' + + self.model, _, self.preprocess = open_clip.create_model_and_transforms( + self.clip_version, pretrained=self.pretrained, cache_dir=cache_dir + ) + + self.model.eval() + self.model.to(device) + + self.device = device + + @torch.no_grad() + def get_clip_score(self, text, image): + if isinstance(image, str): # filenmae + image = Image.open(image) + if isinstance(image, Image.Image): # PIL Image + image = self.preprocess(image).unsqueeze(0).to(self.device) + image_features = self.model.encode_image(image).float() + image_features /= image_features.norm(dim=-1, keepdim=True) + + if not isinstance(text, (list, tuple)): + text = [text] + text = open_clip.tokenize(text).to(self.device) + text_features = self.model.encode_text(text).float() + text_features /= text_features.norm(dim=-1, keepdim=True) + similarity = image_features @ text_features.T + + return similarity + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--captions_path', default='/coco2014/coco2014_val_sampled_30k/captions/', type=str) + parser.add_argument('--fid_images_path', default=None, type=str) + parser.add_argument('--output_path', default='./clip_scores.csv', type=str) + parser.add_argument('--clip_version', default='ViT-L-14', type=str) + args = parser.parse_args() + + # Initialize distributed training + torch.distributed.init_process_group(backend='nccl') + torch.cuda.set_device(int(os.environ['LOCAL_RANK'])) + + captions_path = args.captions_path + print('Init CLIP Encoder..') + encoder = CLIPEncoder(clip_version=args.clip_version) + + # Create output CSV file + with open(args.output_path, 'w', newline='') as csvfile: + fieldnames = ['cfg', 'clip_score'] + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + writer.writeheader() + + # Iterate through subfolders in fid_images_path + for subfolder in os.listdir(args.fid_images_path): + subfolder_path = os.path.join(args.fid_images_path, subfolder) + if os.path.isdir(subfolder_path): + images = sorted( + glob(f'{subfolder_path}/*.png'), key=lambda x: (int(x.split('/')[-1].strip('.png').strip('image'))) + ) + texts = sorted(glob(f'{captions_path}/*.txt')) + print(images[:5], texts[:5]) + # this enables computing clip on the smaller images set + texts = texts[: len(images)] + assert len(images) == len(texts) + print(f'Number of images text pairs: {len(images)}') + + imgs = torch.utils.data.DataLoader( + images, sampler=torch.utils.data.distributed.DistributedSampler(images) + ) + txts = torch.utils.data.DataLoader( + texts, sampler=torch.utils.data.distributed.DistributedSampler(texts) + ) + + ave_sim = torch.tensor(0.0).cuda() + count = 0 + for text, img in zip(tqdm(txts), imgs): + with open(text[0], 'r') as f: + text = f.read().strip() + sim = encoder.get_clip_score(text, img[0]) + ave_sim += sim[0, 0] + count += 1 + if count % 2000 == 0: + print(ave_sim / count) + + torch.distributed.all_reduce(ave_sim) + ave_sim /= len(images) + print(f'The CLIP similarity for CFG {subfolder}: {ave_sim}') + + # Write CLIP score to output CSV file + writer.writerow({'cfg': subfolder, 'clip_score': float(ave_sim)}) diff --git a/scripts/fid-eval-text2img/plot.py b/scripts/fid-eval-text2img/plot.py new file mode 100644 index 000000000000..fbdd9b0c0e42 --- /dev/null +++ b/scripts/fid-eval-text2img/plot.py @@ -0,0 +1,80 @@ +# Copyright (c) 2023, NVIDIA CORPORATION. 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. + +""" +python plot_fid_vs_clip.py \ + --fid_scores_csv path/to/fid_scores.csv \ + --clip_scores_csv path/to/clip_scores.csv +Replace path/to/fid_scores.csv and path/to/clip_scores.csv with the paths +to the respective CSV files. The script will display the plot with FID +scores against CLIP scores, with cfg values annotated on each point. +""" + +import argparse + +import matplotlib.pyplot as plt +import pandas as pd + + +def plot_fid_vs_clip(fid_scores_csv, clip_scores_csv, ax, label): + fid_scores = pd.read_csv(fid_scores_csv) + clip_scores = pd.read_csv(clip_scores_csv) + merged_data = pd.merge(fid_scores, clip_scores, on='cfg').sort_values('cfg') + merged_data.index = range(len(merged_data)) + + ax.plot( + merged_data['clip_score'], merged_data['fid'], marker='o', linestyle='-', label=label + ) # Connect points with a line + + for i, txt in enumerate(merged_data['cfg']): + ax.annotate(txt, (merged_data['clip_score'][i], merged_data['fid'][i])) + + ax.set_xlabel('CLIP Score') + ax.set_ylabel('FID') + ax.set_title('FID vs CLIP Score') + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument( + '--fid_scores_csv', nargs='+', required=True, type=str, help='Paths to the FID scores CSV files' + ) + parser.add_argument( + '--clip_scores_csv', nargs='+', required=True, type=str, help='Paths to the CLIP scores CSV files' + ) + parser.add_argument( + '--labels', nargs='+', required=False, type=str, help='If provided, curves will be named with these names' + ) + parser.add_argument( + '--save_plot_path', required=False, type=str, help='If provided, the plot will be stored at this path' + ) + args = parser.parse_args() + + if not args.labels: + args.labels = [None] * len(args.fid_scores_csv) + + assert len(args.fid_scores_csv) == len(args.clip_scores_csv) == len(args.labels), ( + len(args.fid_scores_csv), + len(args.clip_scores_csv), + len(args.labels), + ) + + fig, ax = plt.subplots() + + for fid, clip, label in zip(args.fid_scores_csv, args.clip_scores_csv, args.labels): + plot_fid_vs_clip(fid, clip, ax, label) + + plt.show() + if args.save_plot_path: + plt.savefig(args.save_plot_path) diff --git a/tutorials/multimodal/DreamBooth Tutorial.ipynb b/tutorials/multimodal/DreamBooth Tutorial.ipynb new file mode 100644 index 000000000000..8651b55d6308 --- /dev/null +++ b/tutorials/multimodal/DreamBooth Tutorial.ipynb @@ -0,0 +1,273 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "a428c1bf", + "metadata": {}, + "source": [ + "# DreamBooth Training / Inference Tutorial\n", + "\n", + "### Note:\n", + "\n", + "Currently, this notebook must be run in a NeMo container. An example command to launch the container:\n", + "\n", + "```bash\n", + "docker run --runtime=nvidia --gpus all -it --rm -v :/opt/NeMo --shm-size=8g -p 8888:8888 \\\n", + " --ulimit memlock=-1 --ulimit stack=67108864 \n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "5af7015b", + "metadata": {}, + "source": [ + "## Introduction\n", + "\n", + "This guide walks you through the process of training DreamBooth in NeMo. [DreamBooth](https://arxiv.org/abs/2208.12242) is originally developed by Google using the Imagen as the base model. NeMo's implementation, however, is based on Stable Diffusion. We'll cover the following topics in this tutorial:\n", + "\n", + "1. Downloading and setting up the dataset along with the pretrained stable diffusion checkpoints.\n", + "2. Conducting training using either the online encoding or pre-cached latents.\n", + "3. Running inference using the fine-tuned model weights." + ] + }, + { + "cell_type": "markdown", + "id": "f99ec204", + "metadata": {}, + "source": [ + "## Prepare Dataset And Checkpoint\n", + "DreamBooth finetunes a pretrained diffusion model using images of a particular object. Sample datasets can be accessed at https://github.com/google/dreambooth. To demonstrate that, we'll use the dataset/dog6 dataset. Here is an example to download the images into a specified directory." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ac481796", + "metadata": {}, + "outputs": [], + "source": [ + "# Create a dataset directory and download instance images\n", + "\n", + "import os\n", + "import wget\n", + "DATA_DIR = '/datasets/instance_dir'\n", + "os.makedirs(DATA_DIR, exist_ok=True)\n", + "\n", + "urls = [f'https://github.com/google/dreambooth/blob/main/dataset/dog6/0{i}.jpg?raw=true' for i in range(5)]\n", + "\n", + "for i, url in enumerate(urls):\n", + " wget.download(url, out=f'{DATA_DIR}/image0{i}.jpg')" + ] + }, + { + "cell_type": "markdown", + "id": "f76fb588", + "metadata": {}, + "source": [ + "Following that, we'll retrieve the pretrained Stable Diffusion checkpoints from Huggingface as our starting point. Two checkpoints are essential: one for the pretrained U-Net weights and the other for the Variational Auto Encoder (VAE)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9f9a134b", + "metadata": {}, + "outputs": [], + "source": [ + "CKPT_DIR = '/ckpts'\n", + "os.makedirs(CKPT_DIR, exist_ok=True)\n", + "\n", + "#There are multiple versions of open-sourced Stable Diffusion checkpoints available on Huggingface, below are the links to U-Net and VAE checkpoints of Stable Diffusion v1.5 at https://huggingface.co/runwayml/stable-diffusion-v1-5/tree/main\n", + "unet_url = 'https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/unet/diffusion_pytorch_model.bin' \n", + "vae_url = 'https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/vae/diffusion_pytorch_model.bin'\n", + "\n", + "wget.download(unet_url, out=f'{CKPT_DIR}/unet.bin')\n", + "wget.download(vae_url, out=f'{CKPT_DIR}/vae.bin')" + ] + }, + { + "cell_type": "markdown", + "id": "6af02b73", + "metadata": {}, + "source": [ + "## Model Config Setup\n", + "\n", + "An example configuration file is readily available at `/opt/NeMo/examples/multimodal/generative/dreambooth/conf/dreambooth.yaml`. We'll kick off with the simplest scenario, finetuning the model using a single node and a single GPU. First, let's review the default configuration file." + ] + }, + { + "cell_type": "markdown", + "id": "c0b99def", + "metadata": {}, + "source": [ + "The trainer section defines number of nodes, number of GPUs and precision used in mixed precision training.\n", + "```yaml\n", + "config.trainer.devices = 1 # number of GPUs\n", + "config.trainer.num_nodes = 1 # number of nodes\n", + "config.trainer.precision = 'bf16-mixed' # mixed precision training with bf16, other options are '16-mixed' (fp16) and '32-true' (tf32)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "6a8f8de5", + "metadata": {}, + "source": [ + "For the CLIP text encoder, we use the NeMo CLIP architecture so one needs to convert the pretrained checkpoint from `open_clip` to Nemo format. Here is the example to run the conversion script." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a54f4d1e", + "metadata": {}, + "outputs": [], + "source": [ + "! python /opt/NeMo/examples/multimodal/foundation/clip/convert_external_clip_to_nemo.py \\\n", + " --arch ViT-L-14 \\\n", + " --version openai \\\n", + " --hparams_file /opt/NeMo/examples/multimodal/foundation/clip/conf/megatron_clip_VIT-L-14.yaml \\\n", + " --nemo_file /ckpts/openai.nemo" + ] + }, + { + "cell_type": "markdown", + "id": "17d5411a", + "metadata": {}, + "source": [ + "After all checkpoints are ready, ensure that the dataset and checkpoints you have prepared are correctly referenced in the configuration file.\n", + "1. `/ckpts/unet.bin` goes to ``model.unet_config.form_pretrained``.\n", + "2. `/ckpts/vae.bin` goes to ``model.first_stage_config.from_pretrained``.\n", + "3. `/ckpts/openai.nemo` goes to ``model.cond_stage_config.restore_from_path``.\n", + "4. `/datasets/instance_dir` goes to ``model.data.instance_dir``." + ] + }, + { + "cell_type": "markdown", + "id": "1ac9fd48", + "metadata": {}, + "source": [ + "## Model Training" + ] + }, + { + "cell_type": "markdown", + "id": "42d7ddd5", + "metadata": {}, + "source": [ + "By default, the images from `instance_dir` are pre-processed using the VAE checkpoint from our earlier steps, which, during training, allows for direct loading of latents and offers a 75% increase in performance. One can however disable this feature by adding `model.use_cached_latents=False` to the following command." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ed75fa5b", + "metadata": {}, + "outputs": [], + "source": [ + "## This is the example command for running dreambooth training\n", + "! python /opt/NeMo/examples/multimodal/generative/dreambooth/dreambooth.py \\\n", + " model.unet_config.from_pretrained=/ckpts/unet.bin \\\n", + " model.unet_config.from_NeMo=False \\\n", + " model.first_stage_config.from_pretrained=/ckpts/vae.bin \\\n", + " model.data.instance_dir=/datasets/instance_dir \\\n", + " model.data.instance_prompt='a photo of a sks dog' " + ] + }, + { + "cell_type": "markdown", + "id": "51296ba9", + "metadata": {}, + "source": [ + "`model.data.instance_prompt` is where we set the special token associated with the particular object we want to inject to the model. Here we use a random word 'sks'. This unique token is a rare combination of letters that is unlikely to be found in typical captions, making it suitable to act as an identifier for the injected object.\n", + "\n", + "\n", + "The experiment results are stored in ``./nemo_experiment.`` However, you can designate a specific log directory using ``exp_manager.explicit_log_dir``. Checkpoints are saved in ``./nemo_experiment/Dreambooth/checkpoints``. After training, the final weights are automatically converted to the ``.nemo`` format, which is the recommended format for inference.\n", + "\n", + "## Model Inference" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2ddbc863", + "metadata": {}, + "outputs": [], + "source": [ + "## This is the example command for running DreamBooth inference\n", + "! torchrun /opt/NeMo/examples/multimodal/generative/dreambooth/dreambooth_infer.py \\\n", + " model.restore_from_path='/opt/NeMo/tutorials/multimodal/nemo_experiments/Dreambooth/checkpoints/Dreambooth.nemo' \\\n", + " infer.num_images_per_prompt=4 \\\n", + " infer.inference_steps=50 \\\n", + " infer.out_path='./DreamBooth_output' \\\n", + " infer.prompts='a photo of a sks dog sleeping'\n" + ] + }, + { + "cell_type": "markdown", + "id": "76c61577", + "metadata": {}, + "source": [ + "### Example of Inference Output" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "77eede7a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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6/Wwww474OUvfznuuOOOTj2YGWeddRZ22WWXyOvRuk6iTek5ufeZz3wGf/M3f4Odd94ZU1NTWL9+PQDgggsuwAEHHIB+v4/tttsOf/7nf46bbrppIn+21nZsKW277bb4zGc+A2MM3va2t421c7G2bI4tueGGG3DSSSfhQQ96EPr9Prbddls861nPGrMJImff+c53cMopp2D77bfHihUr8PKXvxx1XWPt2rV40YtehG222QbbbLMNXve6143pvsVIYjqN6frVNqcvAO8BFplesWIFnv70p+Paa6+N98844wz85V/+JQBgjz32WNTuia6vqgr77bcfLr744s2qf073Gc/gbrvthu9+97v48Y9/jIc85CGbfPYlL3kJzj//fBx77LE47bTT8B//8R84++yzce211y5qEDeHTjrpJGy//fZ485vfjLm5OQBe0E488UTst99+eMMb3oAVK1bgyiuvxMUXX4znP//5AHyHP/WpT8UBBxyAt7zlLVBKRaDy7W9/G4961KO2uC7WWjz1qU/F4x//eLzzne/Epz71Kbz61a/G9PQ03vjGN+IFL3gBnvnMZ+JDH/oQXvSiF+HAAw/EHnvsAQD41a9+hS996Ut41rOehT322AM333wzPvzhD+Pggw/GNddcg/vd734APEh44hOfiN/97nc49dRTseOOO+LTn/40LrvssrH63JU2Liws4JBDDsF1112HV7/61dhjjz1wwQUX4Pjjj8fatWtx6qmn4sEPfjA+8YlP4LWvfS122WUXnHbaaQCA7bffftFyP/jBD2K//fbDUUcdBWMMvvrVr+Kkk06Ccw6vetWrtpjnQrfccgsOO+wwbL/99nj961+PFStW4Prrr48AbxJZa3HiiSfis5/9LL74xS/iiCOOAOAH+9lnn42XvOQleNSjHoX169fjBz/4AX74wx/i0EMP3eo6fv3rX8cxxxyDfffdF2effTbWrFmDE044oTOJAbzROuqoo3DZZZfhxS9+MR7+8IfjkksuwV/+5V/ipptuwjnnnBOfPf744/HP//zPeOELX4hHP/rR+Na3vhXbcV+iuq6xevVqDIdDnHzyydhxxx1x00034Wtf+xrWrl2L5cuXT3zvb/7mb/D2t78dH/7wh/HSl74UAPDRj34Up5xyCo499liceuqpGAwG+O///m/8x3/8Rxz/W0M/+tGPooydccYZaNsWb3nLW7DDDjuMPbu5+u4Nb3gD3vnOd+LII4/E6tWrcfXVV2P16tUYDAZ3Wh/nHI488kj853/+J175yldin332wZe//GUcd9xxY8/+5Cc/wUEHHYSdd94Zr3/96zE9PY1//ud/xtFHH43Pf/7zeMYzntF5/uSTT8Y222yDt7zlLbj++utx7rnn4tWvfjU++9nPxmc+8YlP4LjjjsPq1avxjne8A/Pz8/jgBz+Ixz72sbjyyis7m6LatsXq1avx2Mc+Fu9+97sxNTUFwBvo+fl5vPKVr8S2226L//zP/8R5552H3/zmN3GZ7+Uvfzl++9vf4hvf+AY+8YlPjLXt5S9/OT7+8Y/jhBNOwCmnnIJf//rXeP/7348rr7wSl19+eQznefOb34yzzjoLhx9+OA4//HD88Ic/xGGHHYa6rjfJ503pOQEAb33rW1GWJU4//XQMh0OUZRnr9MhHPhJnn302br75Zrzvfe/D5ZdfjiuvvLLjRLkrtmNraNddd8XBBx+Myy67DOvXr8fs7Gy8N6ktm2tLvv/97+OKK67Ac5/7XOyyyy64/vrr8cEPfhCHHHIIrrnmmtjvQjLWzzzzTHzve9/DRz7yEaxYsQJXXHEFdt11V7z97W/HhRdeiHe96114yEMeEpeEhQaDAW677TYA3jZefvnlOP/88/H85z+/AwY3ty8uvfRSPPWpT8UDHvAAnHHGGVhYWMB5552Hgw46CD/84Q+x++6745nPfCZ+/vOf45/+6Z9wzjnnYLvttovyIPSd73wHX/jCF3DSSSdh2bJl+D//5//gmGOOwY033ohtt9128zuK7yP09a9/nbXWrLXmAw88kF/3utfxJZdcwnVdd5676qqrGAC/5CUv6Vw//fTTGQB/85vfjNcA8Fve8paxb+2222583HHHxd8f+9jHGAA/9rGP5bZt4/W1a9fysmXL+M/+7M94YWGhU4ZzLv6799578+rVq+M1Zub5+XneY489+NBDD91ku3/9618zAP7Yxz4Wrx133HEMgN/+9rfHa3fccQf3+30mIv7MZz4Tr//0pz8da+dgMGBr7dh3qqriv/3bv43X3vOe9zAA/tKXvhSvLSws8D777MMA+LLLLrtb2njuuecyAP7kJz8Zr9V1zQceeCDPzMzw+vXr4/XddtuNjzjiiE2Wl39/lFavXs0PeMADNuv9xeiLX/wiA+Dvf//7iz4j/faud72Lm6bh5zznOdzv9/mSSy7pPPewhz1ss9uzJfTwhz+cd9ppJ167dm289vWvf50B8G677RavfelLX2IAfNZZZ3XeP/bYY5mI+LrrrmNm5v/6r/9iAPya17ym89zxxx+/6Dj6Q6Urr7ySAfAFF1ywyecA8Kte9SpmZj7ttNNYKcUf//jHO888/elP5/322+9ur+PRRx/NvV6Pb7jhhnjtmmuuYa0152p7c/Xd73//ezbG8NFHH9157owzzmAAHX03iT7/+c8zAD733HPjNWstP/GJTxzTT0960pN4//3358FgEK855/gxj3kM77333vGa6NUnP/nJHb3x2te+lrXWUXY3bNjAK1as4Je+9KWdOv3+97/n5cuXd66Lbnz9618/1oZJ+uDss89mIurw+VWvehVPMo3f/va3GQB/6lOf6ly/+OKLO9dvueUWLsuSjzjiiE67/vqv/3qzeM08Wc9ddtllDIAf8IAHdNpS1zWvWrWKH/KQh3Ts0Ne+9jUGwG9+85vjtbtqOxajfKxMolNPPZUB8NVXX73JtmyJLZnUn9/97ncZAP/jP/5jvCZyNlrmgQceyETEr3jFK+K1tm15l1124YMPPnisfZP+d/TRR3fkfEv64uEPfzivWrWK16xZE69dffXVrJTiF73oRfHau971LgbAv/71r8faC4DLsox6WsoAwOedd97Y85ui+8wy8aGHHorvfve7OOqoo3D11Vfjne98J1avXo2dd965s/xw4YUXAsBYsKrMsP7lX/5lq+vw0pe+FFrr+Psb3/gGNmzYgNe//vVj8QKytHDVVVfhF7/4BZ7//OdjzZo1uO2223Dbbbdhbm4OT3rSk/Dv//7vcM5tVX1e8pKXxL9XrFiBBz3oQZiensazn/3seP1BD3oQVqxYgV/96lfxWlVVMS7DWos1a9ZgZmYGD3rQg/DDH/4wPnfxxRdj5513xlFHHRWv9Xq96BURuqttvPDCC7Hjjjviec97XrxWFAVOOeUUbNy4Ed/61re2gjtAv9+Pf69btw633XYbDj74YPzqV7+60+XATZHM7L72ta+haZpNPlvXNZ71rGfha1/7Gi688EIcdthhY2X95Cc/wS9+8Yutrs8o/e53v8NVV12F4447ruPlOvTQQ8fikC688EJorXHKKad0rp922mlgZlx00UUAEJcdTjrp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ZMzPz+MZz3gG9tlnH9R1jSuuuAKf/exnsfvuu+OEE04A4DvluOOOw0c+8hGsXbsWBx98MP7zP/8T559/Po4++mg84QlPiGW+5CUvwSte8Qocc8wxOPTQQ3H11Vfjkksu6XjHNkWzs7M455xz8JKXvASPfOQj8fznPx/bbLMNrr76aszPz+P888+HUgr/8A//gKc+9anYb7/9cMIJJ2DnnXfGTTfdhMsuuwyzs7NRoP636GlPexr+9m//FieccAIe85jH4Ec/+hE+9alPdWaxgE+j8P73vx/Pe97zcOqpp2KnnXbCpz71qejtkBnLXW3jy172Mnz4wx/G8ccfj//6r//C7rvvjs997nO4/PLLce65597pbHISHXbYYSjLEkceeSRe/vKXY+PGjfjoRz+KVatWbbbndzGSrPrPeMYzsOeee2LDhg346Ec/itnZ2UWTqh599NH42Mc+hhe96EWYnZ2NOeP23XdfHHLIITjggAOwcuVK/OAHP8DnPve5u3ze5Nlnn40jjjgCj33sY3HiiSfi9ttvj/nwciV75JFH4glPeALe+MY34vrrr8fDHvYwfP3rX8eXv/xlvOY1r4kz9QMOOADHHHMMzj33XKxZsyamlvn5z38O4A9nmXJz6Jvf/CZe/epX41nPehYe+MAHom1bfOITn4DWGsccc8zEdx796Efjy1/+Mg4//HAce+yx+NKXvoSiKHDYYYdhxx13xEEHHYQddtgB1157Ld7//vfjiCOO2Cq5FTrzzDNx8cUX43GPexxOOumkODnab7/98N///d/xuc3VdzvssANOPfVUvOc978FRRx2FpzzlKbj66qtx0UUXYbvttrvT/jv66KPxqEc9Cqeddhquu+467LPPPvjKV76C22+/HUC3///+7/8ej33sY7H//vvjpS99KR7wgAfg5ptvxne/+1385je/mZjPdFM0OzuLD37wg3jhC1+IP/3TP8Vzn/tcbL/99rjxxhvxL//yLzjooIPuFNTus88+2HPPPXH66afjpptuwuzsLD7/+c9P9NQdcMABAIBTTjkFq1evhtYaz33uc3HwwQfj5S9/Oc4++2xcddVVOOyww1AUBX7xi1/gggsuwPve9z4ce+yx2H777XH66afj7LPPxtOe9jQcfvjhuPLKKyOv724qigLveMc7cMIJJ+Dggw/G8573vJjOZPfdd8drX/vau/2bk+jnP/85PvnJT4KZsX79+ngyx8aNG/He974XT3nKU+60jC2xJU972tPwiU98AsuXL8e+++6L7373u7j00ku3LJ3KVrQPAObn5/G9730P559/Pvbaa694XOCW9MW73vUuPPWpT8WBBx6IF7/4xTG1zPLlyzt5W0Ue3/jGN+K5z30uiqLAkUceefcnUt+ivcf3Il100UV84okn8j777MMzMzNcliXvtddefPLJJ/PNN9/cebZpGj7zzDN5jz324KIo+P73vz+/4Q1v6GwBZ/apEf7qr/6Kt9tuO56amuLVq1fzddddt2hqmcVSiXzlK1/hxzzmMdzv93l2dpYf9ahH8T/90z91nrnyyiv5mc98Jm+77bZcVRXvtttu/OxnP5v/9V//dZPtXiy1zPT09NizBx988MQ0F6NpCgaDAZ922mm80047cb/f54MOOoi/+93v8sEHHzy2pf5Xv/oVH3HEEdzv93n77bfn0047LaaZ+N73vne3tJGZ+eabb+YTTjiBt9tuOy7Lkvfff/9Omxdry6boK1/5Cj/0oQ/lXq/Hu+++O7/jHe/g//f//t+i2/Q3l374wx/y8573PN511125qipetWoVP+1pT+Mf/OAH8Zk8tUxOH/jABxgAn3766czMfNZZZ/GjHvUoXrFiBff7fd5nn334bW9721jKpK2hz3/+8/zgBz+Yq6rifffdl7/whS/wcccd10ktw+xTd7z2ta/l+93vflwUBe+99978rne9q5OGgZl5bm6OX/WqV/HKlSt5ZmaGjz76aP7Zz37GAPjv/u7v7nJ9/7foV7/6FZ944om85557cq/X45UrV/ITnvAEvvTSSzvPYUK6jC9/+ctsjOHnPOc5bK3lD3/4w/z4xz8+yvyee+7Jf/mXf8nr1q27y/X81re+xQcccACXZckPeMAD+EMf+hC/5S1vGUt7srn6rm1bftOb3sQ77rgj9/t9fuITn8jXXnstb7vttp30GovRrbfeys9//vN52bJlvHz5cj7++OP58ssvZwCdlCTMzL/85S/5RS96Ee+4445cFAXvvPPO/LSnPY0/97nPxWcW06uSdkRSV+XXV69ezcuXL+der8d77rknH3/88Z1xt5huZPapeZ785CfzzMwMb7fddvzSl740puHIdU3btnzyySfz9ttvz0Q0xu+PfOQjfMABB3C/3+dly5bx/vvv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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from PIL import Image\n", + "import matplotlib.pyplot as plt\n", + "\n", + "x0 = Image.open('/datasets/instance_dir/image01.jpg')\n", + "x1 = Image.open('./DreamBooth_output/a photo of a sks dog sleeping_2.png')\n", + "\n", + "fig, (ax1, ax2) = plt.subplots(1, 2)\n", + "ax1.imshow(x0)\n", + "ax1.axis('off')\n", + "ax1.set_title('Source image of a \"sks\" dog')\n", + "ax2.imshow(x1)\n", + "ax2.axis('off')\n", + "ax2.set_title('\"sks\" dog generated from DreamBooth')\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/tutorials/multimodal/Multimodal Data Preparation.ipynb b/tutorials/multimodal/Multimodal Data Preparation.ipynb new file mode 100644 index 000000000000..6fdc7da8c2fb --- /dev/null +++ b/tutorials/multimodal/Multimodal Data Preparation.ipynb @@ -0,0 +1,670 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Multimodal Dataset Preparation\n", + "\n", + "First step of pre-training any deep learning model is data preparation. This notebook will walk you through 5 stages of data preparation for training a multimodal model: \n", + "1. Download your Data\n", + "2. Extract Images and Text\n", + "3. Re-organize to ensure uniform text-image pairs\n", + "4. Precache Encodings\n", + "5. Generate Metadata required for training\n", + "\n", + "This notebook will show you how to prepare an image-text dataset into the [WebDataset](https://github.com/webdataset/webdataset) format. The Webdataset format is required to train all multimodal models in NeMo, such as Stable Diffusion and Imagen. \n", + "\n", + "This notebook is designed to demonstrate the different stages of multimodal dataset preparation. It is not meant to be used to process large-scale datasets since many stages are too time-consuming to run without parallelism. For large workloads, we recommend running the multimodal dataset preparation pipeline with the NeMo-Megatron-Launcher on multiple processors/GPUs. NeMo-Megatron-Launcher packs the same 5 scripts in this notebook into one runnable command and one config file to enable a smooth and a streamlined workflow.\n", + "\n", + "Depending on your use case, not all 5 stages need to be run. Please go to (TODO doc link) for an overview of the 5 stages.\n", + " \n", + "We will use a [dummy dataset](https://huggingface.co/datasets/cuichenx/dummy-image-text-dataset) as the dataset example throughout this notebook. This dataset is formatted as a table with one column storing the text captions, and one column storing the URL link to download the corresponding image. This is the same format as most common text-image datasets. The use of this dummy dataset is for demonstration purposes only. **Each user is responsible for checking the content of the dataset and the applicable licenses to determine if it is suitable for the intended use.**\n", + "\n", + "Let's first set up some paths." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "693d0fcd", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"\n", + "You can run either this notebook locally (if you have all the dependencies and a GPU) or on Google Colab.\n", + "\n", + "Instructions for setting up Colab are as follows:\n", + "1. Open a new Python 3 notebook.\n", + "2. Import this notebook from GitHub (File -> Upload Notebook -> \"GITHUB\" tab -> copy/paste GitHub URL)\n", + "3. Connect to an instance with a GPU (Runtime -> Change runtime type -> select \"GPU\" for hardware accelerator)\n", + "4. Run this cell to set up dependencies.\n", + "\"\"\"\n", + "# If you're using Google Colab and not running locally, run this cell.\n", + "\n", + "## Install dependencies\n", + "! pip install img2dataset\n", + "! pip uninstall -y opencv-python-headless\n", + "! pip install opencv-python==4.8.0.74 # https://github.com/opencv/opencv-python/issues/884\n", + "\n", + "### Install NeMo\n", + "BRANCH = 'main'\n", + "!python -m pip install git+https://github.com/NVIDIA/NeMo.git@$BRANCH#egg=nemo_toolkit[all]" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "c06f3527", + "metadata": {}, + "source": [ + "# Multimodal Dataset Preparation\n", + "\n", + "This notebook will show you how to prepare an image-text dataset into the [WebDataset](https://github.com/webdataset/webdataset) format. The Webdataset format is required to train all multimodal models in NeMo, such as Stable Diffusion and Imagen. \n", + "\n", + "This notebook is designed to demonstrate the different stages of multimodal dataset preparation. It is not meant to be used to process large-scale datasets since many stages are too time-consuming to run without parallelism. For large workloads, we recommend running the multimodal dataset preparation pipeline with the NeMo-Megatron-Launcher on multiple processors/GPUs. NeMo-Megatron-Launcher packs the same 5 scripts in this notebook into one runnable command and one config file to enable a smooth and a streamlined workflow.\n", + "\n", + "Depending on your use case, not all 5 stages need to be run. Please go to (TODO doc link) for an overview of the 5 stages.\n", + " \n", + "We will use a [dummy dataset](https://huggingface.co/datasets/cuichenx/dummy-image-text-dataset) as the dataset example throughout this notebook. This dataset is formatted as a table with one column storing the text captions, and one column storing the URL link to download the corresponding image. This is the same format as most common text-image datasets. The use of this dummy dataset is for demonstration purposes only. **Each user is responsible for checking the content of the dataset and the applicable licenses to determine if it is suitable for the intended use.**\n", + "\n", + "Let's first set up some paths." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bef3833e", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "LAUNCHER_DIR = \"/opt/NeMo-Megatron-Launcher\"\n", + "SCRIPT_DIR = os.path.join(LAUNCHER_DIR, \"launcher_scripts/nemo_launcher/collections/dataprep_scripts/multimodal_dataprep\")\n", + "CONF_DIR = \"conf\"\n", + "DATA_DIR = \"dummy_data\"\n", + "os.makedirs(CONF_DIR, exist_ok=True)\n", + "os.makedirs(DATA_DIR, exist_ok=True)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "25d76419", + "metadata": {}, + "source": [ + "\n", + "## Stage 1: Download Parquet Files from HuggingFace\n", + ">**Alternative workflows:**\n", + ">- **If your dataset is not hosted on HuggingFace or your dataset does not contain .parquet files, please move on to Stage 2**\n", + ">- **If you want to experiment with local image and text files, please see Appendix 1 for a tutorial to create a WebDataset from local images, then move on to Stage 3**\n", + ">- **If you have a dataset in the WebDataset format already and only want to precache the embeddings, please move on to Stage 4**\n", + "\n", + "In this stage, we download the raw data files (.parquet format) from HuggingFace. The parquet files should contain the text captions and the urls to download each image. We then optionally subpartition the parquet file so that the next stage can be parallelized more efficiently.\n", + "\n", + "Script: download_parquet.py\n", + "\n", + "Arguments:\n", + "- `dataset_repo_id`: huggingface dataset repo id, in the format of {user_or_company}/{dataset_name}. See [here](https://huggingface.co/datasets?task_categories=task_categories:text-to-image&sort=downloads) for a list of datasets on HuggingFace.\n", + "- `output_dir`: output of this stage\n", + "- `parquet_subpartitions`: increase the number of partitions to reduce the image downloading time (next stage) of each task. Useful if the next stage is parallelized over multiple tasks. We will use 3 for this example to keep the run time of subsequent stages short.\n", + "- `parquet_pattern`: `glob` pattern to use to find the parquet files. Defaults to `*.parquet` (all files that end with the extension)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a06a904b", + "metadata": {}, + "outputs": [], + "source": [ + "! python $SCRIPT_DIR/download_parquet.py \\\n", + " dataset_repo_id='cuichenx/dummy-image-text-dataset' \\\n", + " output_dir=$DATA_DIR/parquet \\\n", + " parquet_subpartitions=3 \\\n", + " parquet_pattern='*.parquet'" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "ebfd2565", + "metadata": {}, + "source": [ + "**Milestone**: You should now see 3 files in the output directory `$DATA_DIR/parquet/dummy_dataset50000.parquet_parts`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3ccc6d7e", + "metadata": {}, + "outputs": [], + "source": [ + "! ls $DATA_DIR/parquet/dummy_dataset50000.parquet_parts | wc -l\n", + "# should output 3" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "56d5dbb9", + "metadata": {}, + "source": [ + "\n", + "## Stage 2: Download Images Files\n", + ">**Alternative workflows:**\n", + ">- **If your dataset is not hosted on HuggingFace or your dataset does not contain .parquet files, please consult the README page of [img2dataset](https://github.com/rom1504/img2dataset) and modify the command to call img2dataset.**\n", + "\n", + "In this stage, we extract the images and texts from the parquet files into the WebDataset format using an open-source tool, [img2dataset](https://github.com/rom1504/img2dataset). \n", + "This stage will typically benefit from a large degree of parallelism (e.g. thousands of tasks). We will pretend there are 3 tasks running (3 was set in the previous stage), and only work on the first of the 3 parquet subpartitions (i.e. shards) in this notebook.\n", + "\n", + "Script: download_images.py\n", + "\n", + "Environment variables (automatically set by SLURM if running with NeMo-Megatron-Launcher):\n", + "- `SLURM_ARRAY_TASK_COUNT`: total number of tasks, should be set to the number of parquet files in `$DATA_DIR/parquet/dummy_dataset50000.parquet_parts`. (i.e. `parquet_subpartitions` x `num_parquets_downloaded`)\n", + "- `SLURM_ARRAY_TASK_ID`: id of the current task (0 <= SLURM_ARRAY_TASK_ID < SLURM_ARRAY_TASK_COUNT)\n", + "\n", + "Arguments:\n", + "- `input_dir`: parquet download dir from the previous stage.\n", + "- `output_dir`: output of this stage\n", + "- `parquet_pattern`: see stage 1\n", + "- `download_num_processes`: number of processes to use. This should be set to number of CPUs in the machine\n", + "- `download_num_threads`: number of threads to use. This should be tuned to balance cpu usage, internet bandwidth and disk bandwidth. \n", + "- `img2dataset_additional_arguments`: see [img2dataset](https://github.com/rom1504/img2dataset) for complete list of parameters and [here](https://github.com/rom1504/img2dataset/tree/main/dataset_examples) for some examples. In this example, we use encode_quality=95 for jpeg compression quality, and resize_mode=no to keep the original images on disk. You can also override these arguments to suit your own needs: input_format (default is parquet), caption_col (default is TEXT), url_col (default is URL)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72d7e0f8", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# pretend that we're the first task out of 3 tasks\n", + "! SLURM_ARRAY_TASK_ID=0 SLURM_ARRAY_TASK_COUNT=3 python $SCRIPT_DIR/download_images.py \\\n", + " input_dir=$DATA_DIR/parquet \\\n", + " output_dir=$DATA_DIR/tarfiles_raw \\\n", + " parquet_pattern='*.parquet' \\\n", + " download_num_processes=2 \\\n", + " download_num_threads=16 \\\n", + " \"img2dataset_additional_arguments={{encode_quality:95,resize_mode:10}}\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "Note: In this dummy dataset, you will likely see a success rate of 1.000 (no failures). However, for read datasets, the success rate will always be much less than 1.000" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "27cf740d", + "metadata": {}, + "source": [ + "**Milestone**: You should now see tar files (along with other files) in the output directory `$DATA_DIR/tarfiles_raw/part.0.parquet`. Inside each tar file, you should see the .jpg image, the corresponding .txt caption, and .json metadata." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b1b6477e", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "! ls $DATA_DIR/tarfiles_raw/part.0.parquet | head -n 6" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7f8572f2", + "metadata": {}, + "outputs": [], + "source": [ + "! tar -tf $DATA_DIR/tarfiles_raw/part.0.parquet/00000.tar | tail -n 6" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "09fea68d", + "metadata": {}, + "source": [ + "## Stage 3: Reorganize Tarfiles to Same Number of Image-Text Pairs" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "2d0cbfc0", + "metadata": {}, + "source": [ + "*Note: This stage is required to train multimodal models in NeMo.*\n", + "\n", + "In this stage, we reorganize the contents of tar files from the download_images step, so that the tar files are uniform\n", + "(i.e. each containing an equal number (usually 1000) of training examples (image-text pairs)).\n", + "The tar files created from the download_images step are not uniform, because there is always a portion of images\n", + "that fail to download or are no long available.\n", + "Uniform tar files are important if a sequential sampler is used during training (i.e. not infinite sampler).\n", + "Uniform tar files are also important for precaching because a sequential sampler is used there.\n", + "\n", + "Script: reorganize_tar.py\n", + "\n", + "Environment variables (automatically set by SLURM if running with NeMo-Megatron-Launcher):\n", + "- `SLURM_ARRAY_TASK_COUNT`: total number of tasks, should be set to parquet_subpartitions x num_parquets_downloaded\n", + "- `SLURM_ARRAY_TASK_ID`: id of the current task (0 <= `SLURM_ARRAY_TASK_ID` < `SLURM_ARRAY_TASK_COUNT`)\n", + "\n", + "Arguments:\n", + "- `input_dir`: image download dir from the previous stage.\n", + "- `output_dir`: output of this stage\n", + "- `file_ext_in_tar`: target file extensions in each tar file to transfer to the reorganized tar files. In this example, we have .jpg, .txt, and .json in the downloaded tar files, but we will only keep the image and text and discard the .json metadata.\n", + "- `tar_chunk_size`: number of training examples in each output tar file\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bc3d1e60", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "! SLURM_ARRAY_TASK_ID=0 SLURM_ARRAY_TASK_COUNT=1 python $SCRIPT_DIR/reorganize_tar.py \\\n", + " input_dir=$DATA_DIR/tarfiles_raw \\\n", + " output_dir=$DATA_DIR/tarfiles_reorganized \\\n", + " tar_chunk_size=1000 \\\n", + " file_ext_in_tar=[.jpg,.txt]" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "95c77097", + "metadata": {}, + "source": [ + "**Milestone**: You should now see tar files (along with other files) in the output directory `$DATA_DIR/tarfiles_reorganized/`. Inside each tar file, you should see exactly 1000 pairs of .jpg image and .txt caption, for a total of 2000 files." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4495428f", + "metadata": {}, + "outputs": [], + "source": [ + "! tar -tf $DATA_DIR/tarfiles_reorganized/task0000/00001.tar | wc -l\n", + "# should output 2000" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "09b83dd7", + "metadata": {}, + "source": [ + "## Stage 4: Precache Encodings\n", + "\n", + ">**Alternative workflows:**\n", + ">- **If you're only testing out the NeMo text2image models and do not care about good training performance, you can skip this step and move on to Stage 5.**\n", + "\n", + "### General Format\n", + "\n", + "Precaching refers to the offline computation of image and text encodings prior to training a model. This technique\n", + "is suitable for any model that uses pretrained, frozen encoders during training.\n", + "By using precached encodings, embeddings for image and text do not need to be recomputed in each epoch,\n", + "thereby significantly improving training throughput (up to 60% higher).\n", + "Precached encodings are saved in the format of WebDataset.\n", + "Each tar file contains one pickle file to store all the modality embeddings for each training example. Optionally,\n", + "the tar file may also include the original image or text files\n", + "\n", + "```\n", + "t0_r0_0.tar\n", + "|---- 00000.pickle\n", + "|---- 00000.jpg (optional)\n", + "|---- 00000.txt (optional)\n", + "|---- 00001.pickle\n", + "|---- 00001.jpg (optional)\n", + "|---- 00001.txt (optional)\n", + "...\n", + "```\n", + "Each pickle file stores one python dictionary, with key value pairs storing the embedding name and the embedding as a\n", + "numpy array.\n", + "\n", + "### Precaching Config\n", + "Configuration for precaching can be extensive and intricate for some models. To maintain clarity and ensure an\n", + "organized workflow, we utilize a separate YAML file for these configurations. The YAML file looks like this:\n", + "\n", + "```\n", + "encodings:\n", + " - modality: image\n", + " extension: jpg\n", + " key: autoencoderkl_image\n", + " precision: 16\n", + " encoder_config:\n", + " cls: nemo.collections.multimodal.models.text_to_image.stable_diffusion.ldm.autoencoder.AutoencoderKL\n", + " ... (kwargs to initialize the encoder)\n", + " - modality: text\n", + " extension: txt\n", + " key: clip-vit-large-patch14_text\n", + " precision: 32\n", + " store_pad_tokens: True\n", + " encoder_config:\n", + " cls: nemo.collections.multimodal.modules.stable_diffusion.encoders.modules.FrozenCLIPEmbedder\n", + " ... (kwargs to initialize the encoder)\n", + "```\n", + "\n", + "In this YAML file, the encodings field specifies a list of embeddings to be saved in the pickle file.\n", + "Each entry can have the following attributes:\n", + "\n", + "\n", + "- `modality`: either image or text\n", + "- `extension`: file extension for this modality in the tar file (e.g. 'jpg', 'txt')\n", + "- `key`: dictionary key for the encoding. It is recommended to follow the format `{model_name}-{model_variant}_{modality}`, if applicable. e.g. `clip-vit-large-patch14_text`\n", + "- `precision`: precision of the stored tensors (32 or 16)\n", + "- `store_pad_tokens`: Whether to store the PAD tokens. Not storing PAD tokens can significantly reduce disk usage, but the training script must account for this. Ignored for image modality.\n", + "- `encoder_config`: This dictionary must contain `cls` which points to the location of the encoder class. The rest of the parameters are treated as kwargs to initiate the encoder class.\n", + " - Note: the encoder class must implement an `encode` or `__call__` function. If `store_pad_tokens`, this function must return the encoded tensor. Otherwise, this function must return a tuple of (encoded_tensor, mask). The mask is needed so the script knows which tokens are pad tokens and should be ignored for caching. A mask value of 1 denotes regular tokens, and 0 denotes pad tokens.\n", + "\n", + "\n", + "Note that it is not required to have only one encoding per modality, in the case of multiple encoders.\n", + "The `encodings` field is designed as a list to account for this. For example, it's possible to have one image embedding\n", + "and two text embeddings (e.g. one from CLIP and one from T5) and both are used during training. An example is shown below.\n", + "\n", + "```\n", + "encodings:\n", + " - modality: image\n", + " extension: jpg\n", + " key: image_emb\n", + " encoder_config:\n", + " cls: path.to.ImageEncoder\n", + " ...\n", + " - modality: text\n", + " extension: txt\n", + " key: text_emb_1\n", + " encoder_config:\n", + " cls: path.to.TextEncoder1\n", + " ...\n", + " - modality: text\n", + " extension: txt\n", + " key: text_emb_2\n", + " encoder_config:\n", + " cls: path.to.TextEncoder2\n", + " ...\n", + "```\n", + "\n", + "In this tutorial, we will show an example of precaching workflow for Stable Diffusion. " + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "27b26036", + "metadata": {}, + "source": [ + "Let's download an example precaching config file ## TODO modify this path" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2bd39f5", + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "! wget TODO_github_link/precache_sd.yaml -P $CONF_DIR/" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "986045fe", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "from omegaconf import OmegaConf\n", + "precache_cfg = OmegaConf.load(os.path.join(CONF_DIR, \"precache_sd.yaml\"))\n", + "# visualize the config\n", + "print(OmegaConf.to_yaml(precache_cfg))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "f5bee705", + "metadata": {}, + "source": [ + "There are a few things to note about this config file:\n", + "- `batch_size_per_GPU`: this should be set to as much as your GPU memory can fit\n", + "- `save_original_in_tar`: for SD, original images or text are not used during training (if using precached encodings), so we can leave this empty. If you want the original image and text copied into the tar file, you can set this to [image, text]. \n", + "\n", + "In this example, we need to download the weights of the image autoencoder from the HuggingFace [Stable Diffusion v1.5 repo](https://huggingface.co/runwayml/stable-diffusion-v1-5/blob/main/vae/diffusion_pytorch_model.bin). Text encoder weights will be downloaded automatically when the model `FrozenCLIPEmbedder` is initialized." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d6804d4", + "metadata": {}, + "outputs": [], + "source": [ + "! wget https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/vae/diffusion_pytorch_model.bin" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "d2e5d6aa", + "metadata": {}, + "source": [ + "Then, we modify the `from_pretrained` field with the weights file, and save this config as a yaml file to disk.\n", + "We also adjust the config to use 1 GPU for this tutorial." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d509be7c", + "metadata": {}, + "outputs": [], + "source": [ + "precache_cfg.encodings[0].encoder_config.from_pretrained = 'diffusion_pytorch_model.bin'\n", + "precache_cfg.lightning.devices=1\n", + "# precache_cfg.batch_size_per_GPU=8 # adjust if needed\n", + "\n", + "OmegaConf.save(precache_cfg, os.path.join(CONF_DIR, \"precache_sd_example.yaml\"))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "765d281e", + "metadata": {}, + "source": [ + "Now we can run the precaching script. \n", + "\n", + "Script: precache_encodings.py\n", + "\n", + "Environment variables (automatically set by SLURM if running with NeMo-Megatron-Launcher):\n", + "- `SLURM_ARRAY_TASK_COUNT`: total number of tasks, should be set to parquet_subpartitions x num_parquets_downloaded\n", + "- `SLURM_ARRAY_TASK_ID`: id of the current task (0 <= `SLURM_ARRAY_TASK_ID` < `SLURM_ARRAY_TASK_COUNT`)\n", + "\n", + "Arguments:\n", + "- `input_dir`: reorganized tar dir from the previous stage.\n", + "- `output_dir`: output of this stage\n", + "- `tar_chunk_size`: number of training examples in each output tar file\n", + "- `precache_cfg`: precaching config file as describe above\n", + "\n", + "This stage will typically benefit from a large degree of parallelism (e.g. thousands of tasks). We will pretend that we are the first task out of 2 tasks. Since the input directory is already 1/3 of the full dataset, the result of this stage in the tutorial will be 1/6 of the dataset." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "63c9b44c", + "metadata": {}, + "outputs": [], + "source": [ + "! SLURM_ARRAY_TASK_ID=0 SLURM_ARRAY_TASK_COUNT=2 python $SCRIPT_DIR/precache_encodings.py \\\n", + " input_dir=$DATA_DIR/tarfiles_reorganized \\\n", + " output_dir=$DATA_DIR/tarfiles_precached \\\n", + " tar_chunk_size=1000 \\\n", + " precache_config_path=conf/precache_sd_example.yaml" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "76082b01", + "metadata": {}, + "source": [ + "**Milestone**: You should now see tar files (along with other files) in the output directory `$DATA_DIR/tarfiles_precached/`. Inside each tar file, you should see exactly 1000 .pickle files storing the image and text embeddings." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e93883ba", + "metadata": {}, + "outputs": [], + "source": [ + "! tar -tf `ls -d $DATA_DIR/tarfiles_precached/* | head -n 1` | wc -l\n", + "# should output 1000" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "6394e07f", + "metadata": {}, + "source": [ + "## Stage 5: Generate `wdinfo` Metadata\n", + "\n", + "This stage generates the metadata required by the NeMo multimodal training data pipeline. The metadata contains the chunk size, the total size of dataset, and most importantly, the list of tarfiles.\n", + "\n", + "The metadata will only include tarfiles with exactly `tar_chunk_size` (1000 in this tutorial) examples, and ignore/discard incomplete tar files. Incomplete tar files are the last tar file generated by each process which contain the leftover training examples, most likely less than `tar_chunk_size`. \n", + "\n", + "In the case of a high degree of parallelism, there can be a significant number of incomplete tarfiles leading to a waste of discarded training examples. Therefore, before creating the metadata file, this stage will also find all the incomplete tar files generated in the previous stage, and combine them in a single-process script so that there is at most one incomplete tarfile throughout the entire dataset.\n", + "\n", + "Script: generate_wdinfo.py\n", + "\n", + "Arguments:\n", + "- `input_dir`: output tar dir from stage 3 or stage 4.\n", + "- `output_wdinfo_path`: output of this stage\n", + "- `tar_chunk_size`: number of training examples in each output tar file\n", + "- `file_ext_in_tar`: see explanation in Stage 3. If you performed precaching without copying any files from the source tar (i.e. save_original_in_tar: null in precache_sd_example.yaml) then this should be [.pickle]\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5b72a03a", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "! python $SCRIPT_DIR/generate_wdinfo.py \\\n", + " input_dir=$DATA_DIR/tarfiles_precached \\\n", + " output_wdinfo_path=$DATA_DIR/wdinfo.pkl \\\n", + " tar_chunk_size=1000 \\\n", + " file_ext_in_tar=[.pickle]" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "a9c8e2ca", + "metadata": {}, + "source": [ + "**Milestone**: You should now see the wdinfo.pkl file generated. The content of the file is printed above." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9cc2e2a6", + "metadata": {}, + "outputs": [], + "source": [ + "! test -f $DATA_DIR/wdinfo.pkl && echo \"File exists\" || echo \"File does not exist\"" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": false + }, + "source": [ + "## Appendix 1: Create a WebDataset from Local Image Text Files\n", + "\n", + "\n", + "If you have image and text files already downloaded, you can quickly convert your dataset to the WebDataset format and proceed with Stages 3-5 of this tutorial without wasting any time on download. Simply follow the steps below.\n", + "\n", + "1. Manipulate your dataset so that each text caption is stored in a single file, and shares the same file path as the corresponding image, except the extension. The file path can contain subfolders. An example is shown below\n", + "\n", + " ```bash\n", + " > cd dataset\n", + " > find . -type f\n", + " ./train/n00001234/00010000.jpg ./train/n00001234/00010000.txt\n", + " ./train/n00001234/00010001.jpg ./train/n00001234/00010001.txt\n", + " ./train/n00001234/00010002.jpg ./train/n00001234/00010002.txt\n", + " ./train/n00001234/00010003.jpg ./train/n00001234/00010003.txt\n", + " ./train/n00001234/00010004.jpg ./train/n00001234/00010004.txt\n", + " ./train/n00001235/00010000.jpg ./train/n00001235/00010000.txt\n", + " ./train/n00001235/00010001.jpg ./train/n00001235/00010001.txt\n", + " ...\n", + " > cd ..\n", + " ```\n", + "\n", + "2. Run this command to create of tarball of the folder with sorted file names. It is important for WebDataset to have the image and text files in consecutive blocks on disk, hence the sorting is necessary.\n", + "\n", + "```bash\n", + "> tar --sort=name -cf dataset.tar dataset/\n", + "```\n", + "\n", + "For more information, please visit [Creating a WebDataset](https://github.com/webdataset/webdataset#creating-a-webdataset)\n", + "\n", + "After this, you can proceed with Stage 3 of the tutorial.\n", + "Note: if you can use a script to create folders with exactly `tar_chunk_size` (1000 in the tutorial) image-text pairs, and create multiple tarfiles each with `tar_chunk_size` pairs of data, then you can skip Stage 3 and proceed with Stage 4 of the tutorial." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/tutorials/multimodal/README.md b/tutorials/multimodal/README.md new file mode 100644 index 000000000000..3da7c87d7c08 --- /dev/null +++ b/tutorials/multimodal/README.md @@ -0,0 +1,15 @@ +# NeMo MultiModal Tutorials + + +The goal of this collection of IPython notebooks is to familiarize users with NeMo multimodal offerings. By launching the latest Nemo container, users can easily step through the tutorials, conduct experiments, and build custom application. + +#### Getting Started Checklist +* Register a NGC account +* Generate your NGC API key for pulling NeMo contrainer (please refer to this [video](https://youtu.be/yBNt4qSnn0k?feature=shared) for details) +* Make sure the container host system meets the minimal GPU requirement (i.e. NVIDIA A100 GPU) + +## What does this repository contain? +This repository contains the following resources: +* [Data Preparation](./Multimodal%20Data%20Preparation.ipynb) +* [Train And Infer Stable Diffusion Model](./Stable%20Diffusion%20Tutorial.ipynb) +* [Train DreanBooth Model](./DreamBooth%20Tutorial.ipynb) diff --git a/tutorials/multimodal/Stable Diffusion Tutorial.ipynb b/tutorials/multimodal/Stable Diffusion Tutorial.ipynb new file mode 100644 index 000000000000..ed794356f280 --- /dev/null +++ b/tutorials/multimodal/Stable Diffusion Tutorial.ipynb @@ -0,0 +1,275 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "d874e23f-9631-48e0-b635-84e7280bf07b", + "metadata": {}, + "source": [ + "# Stable Diffusion Training / Inference Tutorial\n", + "\n", + "### Note:\n", + "Currently, this notebook must be run in a NeMo container. An example command to launch the container:\n", + "\n", + "```\n", + "docker run --gpus all -it --rm -v :/opt/NeMo --shm-size=8g \\\n", + " -p 8888:8888 --ulimit memlock=-1 --ulimit \\\n", + " stack=67108864 \n", + "```\n", + "\n", + "## Introduction\n", + "\n", + "This notebook illustrates how to train and perform inference using Stable Diffusion with the NeMo Toolkit. For the sake of brevity, we've chosen to use Stable Diffusion as an example to demonstrate the foundational process of training and inferencing with Text2Img models. However, you can apply the same approach to other foundational Text2Img models, such as Imagen.\n", + "\n", + "The implementation of Stable Diffusion is based on [High-Resolution Image Synthesis with Latent Diffusion Models](https://arxiv.org/abs/2112.10752).\n", + "\n", + "This tutorial will guide you through the following topics:\n", + "\n", + "1. Training a Stable Diffusion model.\n", + "2. Performing inference with the trained model.\n", + "\n", + "## Datasets\n", + "\n", + "Please refer to [ADD LINK]() for how to prepare a training dataset for Stable diffusion.\n", + "\n", + "For a pre-cached Stable Diffusion dataset, each webdataset tar file should, at a minimum, include the pickle files that store the pre-cached image and text features:\n", + "\n", + "```\n", + "t0_r0_0.tar\n", + "|---- 0000.pickle\n", + "|---- 0001.pickle\n", + "...\n", + "```\n", + "\n", + "For non-precached Stable Diffusion dataset, each webdataset tar file should contain the raw texts and corresponding images:\n", + "\n", + "```\n", + "t0_r0_0.tar\n", + "|---- 0000.jpg\n", + "|---- 0000.txt\n", + "|---- 0001.jpg\n", + "|---- 0001.txt\n", + "...\n", + "```\n", + "\n", + "## Encoders Preparation\n", + "\n", + "Depending on whether you precache the dataset, you might also need to first download the image and/or text encoders.\n", + "\n", + "### Option 1: Training on Non-Precached Dataset (Use Encoders During Training)\n", + "\n", + "#### A. Prepare VAE\n", + "To download the default VAE for Stable Diffusion:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "730cd137-0fce-4bab-8ac7-219e5c55faf2", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "! wget https://huggingface.co/CompVis/stable-diffusion-v1-4/resolve/main/vae/diffusion_pytorch_model.bin\n", + "! mkdir -p /ckpts\n", + "! mv diffusion_pytorch_model.bin /ckpts/vae.bin" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "fef8b245-7cee-4048-a9ec-3ada90432a89", + "metadata": {}, + "source": [ + "The above command will download the default VAE weights from HuggingFace and save it to `/ckpts/vae.bin`.\n", + "\n", + "**Note**: if you want to customize the saved location, make sure it is also reflected in your training config.\n", + "#### B. Prepare Text Encoder\n", + "For the text encoder used in Stable Diffusion, you can either use [HuggingFace CLIP ViT-L/14 model](https://huggingface.co/openai/clip-vit-large-patch14) or use NeMo's CLIP-ViT. NeMo Stable Diffusion also supports native CLIP ViT model trained in NeMo framework.\n", + "\n", + "Make sure the following settings are used in `cond_stage_config`:\n", + "\n", + "```\n", + " cond_stage_config:\n", + " # For compatibility with the previous version that uses HuggingFace CLIP model\n", + " _target_: nemo.collections.multimodal.modules.stable_diffusion.encoders.modules.FrozenCLIPEmbedder\n", + " version: openai/clip-vit-large-patch14\n", + " device: cuda\n", + " max_length: 77\n", + " capture_cudagraph_i rs: ${model.capture_cudagraph_ters}\n", + "```" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "e52057c4-83ee-4f21-a11c-11a5c367a0b8", + "metadata": {}, + "source": [ + "Alternatively, you can use the CLIP model in `.nemo` format . This can be achieved by using the provided NeMo script to download and convert the CLIP model via the following command:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ada77920-06f5-43f3-bb26-82d9daabde8f", + "metadata": {}, + "outputs": [], + "source": [ + "! python examples/multimodal/foundation/clip/convert_external_clip_to_nemo.py \\\n", + " --arch ViT-L-14 \\\n", + " --version openai \\\n", + " --hparams_file /opt/NeMo/examples/multimodal/foundation/clip/conf/megatron_clip_VIT-L-14.yaml \\\n", + " --nemo_file /ckpts/openai.nemo" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "34a385ff-f8ff-4e64-bd6f-b814be388598", + "metadata": {}, + "source": [ + "When using `.nemo` ViT model, you can use the default `cond_stage_config`:\n", + "\n", + "```\n", + " cond_stage_config:\n", + " _target_: nemo.collections.multimodal.modules.stable_diffusion.encoders.modules.FrozenMegatronCLIPEmbedder\n", + " restore_from_path: /ckpts/openai.nemo\n", + " device: cuda\n", + " freeze: True\n", + " layer: \"last\"\n", + "```" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "8854eb7a-e822-43f6-a1d5-12357049485a", + "metadata": {}, + "source": [ + "\n", + "### Option 2: Training on Precached Dataset (Training UNet Only)\n", + "\n", + "When using precached dataset (please refer to the [Dataset Tutorial](ADD_LINK) for details), every text feature and image feature are stored as key-value pairs in `.pickle` file:\n", + "\n", + "```\n", + "{\n", + " image_key: torch.Tensor(),\n", + " text_key: torch.Tensor(),\n", + "}\n", + "```\n", + "\n", + "Make sure in the training config, `cond_stage_key` is associated with `text_key` and `first_stage_key` is associated with `image_key`.\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "5762427b-f60c-4dfd-8318-e55771b25354", + "metadata": {}, + "source": [ + "## Model Config Setup\n", + "\n", + "Now we will begin setting up the config file needed for Stable Diffusion training. We will use [sd_train.yaml]() as the template.\n", + "\n", + "1. Modify `model.data.train.dataset_path` so that it has all the webdataset info files you want to train on\n", + "2. Modify `model.data.webdataset.local_root_path` to point to your dataset path\n", + "3. Make sure VAE path `model.first_stage_config.from_pretrained` is adjusted if using non-precached dataset\n", + "4. Make sure the text encoder config is correct (detailed above)\n", + "5. Configure `exp_manager.exp_dir` for experiment save directory\n", + "6. Configure `exp_manager.wandb_logger_kwargs` and/or `exp_manager.create_tensorboard_logger` if needed" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "70f858b3-f7d5-4678-b380-80582337bc23", + "metadata": {}, + "source": [ + "**Note**: Please refer to NeMo Toolkit Developer Guide's Stable Diffusion page for more details on in-depth customizations, including all available optimizations.\n", + "\n", + "## Training\n", + "\n", + "Once everything is set up, training stable diffusion is as simple as running:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "589e3a14-c881-4a56-b2bd-370653059dfc", + "metadata": {}, + "outputs": [], + "source": [ + "! torchrun /opt/NeMo/examples/multimodal/generative/stable_diffusion/sd_train.py trainer.max_steps=100 model.data.synthetic_data=True" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "892d72dd-c4d7-4ca4-a948-168e187af65c", + "metadata": {}, + "source": [ + "Intermediate checkpoints (during training) and final checkpoint will be saved to `exp_manager.exp_dir` folder. Note that here we use synthetic data for demo purpose." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "087c8b9a-92c3-43d3-86a3-bf7e848dfbd2", + "metadata": {}, + "source": [ + "## Inference\n", + "\n", + "Stable Diffusion inference needs a trained NeMo Stable Diffusion checkpoint, along with both the image encoder (VAE) and text encoder (CLIP). The checkpoint can be either a fully trained `.nemo` checkpoint or an intermediate checkpoint from training (typically in `.ckpt` format). Both `.nemo` and `.ckpt` checkpoints can be used for inference. For information on downloading the encoders, please refer to the previous section.\n", + "\n", + "### Inference Config Setup\n", + "\n", + "Now we will begin setting up the config file needed for Stable Diffusion inference. We will use [sd_infer.yaml]() as the template.\n", + "\n", + "We generally use [Classifier Free Guidance](https://arxiv.org/abs/2207.12598) for better visual quality, which can be set at `infer.unconditional_guidance_scale`.\n", + "\n", + "NeMo Stable Diffusion supports multiple samplers. Please refer to the developer guide for more details. Samplers can be set at `infer.sampler_type`.\n", + "\n", + "Inference supports a batch of text prompts, which can be set at `infer.prompts`. One can also generate a configurable number of images per prompt by setting `infer.num_images_per_prompt`. Generated images will be saved to `infer.out_path`.\n", + "\n", + "You will also need to set the model checkpoint path at `model.restore_from_path`.\n", + "\n", + "### Running the Inference\n", + "\n", + "Once everything is set up, Stable Diffusion inference is as simple as running:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e676c5d-d711-489e-8ab7-3ee20046d88d", + "metadata": {}, + "outputs": [], + "source": [ + "! ! torchrun /opt/NeMo/examples/multimodal/generative/stable_diffusion/sd_infer.py model.restore_from_path='/opt/NeMo/tutorials/multimodal/nemo_experiments/stable-diffusion-train/checkpoints/stable-diffusion-train.nemo'" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}