-
Notifications
You must be signed in to change notification settings - Fork 32.3k
Adding imagebind #30690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
EduardoPach
wants to merge
176
commits into
huggingface:main
Choose a base branch
from
EduardoPach:adding-imagebind
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Adding imagebind #30690
Changes from all commits
Commits
Show all changes
176 commits
Select commit
Hold shift + click to select a range
d72c9a3
initial commit for ImageBind model
dg845 6be5464
add initial testing code for ImageBind model
dg845 190e727
Add config classes for remaining modalities (audio, depth, thermal, I…
dg845 3692190
Update ImageBindOutput with remaining modalities (audio, depth, therm…
dg845 4037f6a
Add embedding classes for image-like modalities (vision, audio, depth…
dg845 970dc5d
Implement IMU embedding class.
dg845 ffd1460
Add module to convert still images into video frames.
dg845 ee74943
Add implementation for shared model encoder blocks.
dg845 93ce319
Add key and value biases to ImageBindAttention.
dg845 c7968d6
Add ImageBind heads and postprocessors.
dg845 0000bbc
Update ImageBindModel.forward to compare images against any other mod…
dg845 a1bdbf7
Separate normalized embeddings into their own output field.
dg845 69fa517
Add initial tester/test classes for remaining modalities (audio, dept…
dg845 a8341e4
Create initial audio feature extractor based on ASTFeatureExtractor (…
dg845 ac926ad
Add image processing classes for remaining image-like modalities excl…
dg845 e151140
Add IMU feature extractor class declaration and add feature extractor…
dg845 789559a
Update ImageBindAudioFeatureExtractor to use ImageBind-specific audio…
dg845 84851a5
Add final dropout layer to ImageBindImuTransformer.
dg845 43016df
Fix typo
dg845 93d7749
Change model test parameters to be closer to ImageBind defaults.
dg845 1b4bb43
Update audio feature extractor to output batched and clipped audio.
dg845 d9a0a80
Add modeling support for batched and clipped vision and audio inputs.
dg845 b5d46cd
Update ImageBind image processor to always output video (batched and …
dg845 029d424
Merge branch 'main' into imagebind-model
dg845 a9d432c
Implement ImageBindDepthImageProcessor.
dg845 90543ce
Implement ImageBindImuFeatureExtractor.
dg845 8ce499b
Fix some modeling code bugs.
dg845 484cd3f
Move Image2Video logic into RGBDTPatchEmbedding.
dg845 284ffe5
Fix attention kv bias initialization bug.
dg845 c5d1e3b
Implement ImageBind conversion script.
dg845 4a8aaf5
Fix bugs in ImageBind conversion script.
dg845 06f9536
Fix conversion script test configs.
dg845 f691396
Fix ImageBindAudioEmbeddings.
dg845 ba64517
Fix num_patches calculation.
dg845 78e537d
Fix audio num_patches calculation in conversion script.
dg845 befcc26
Merge branch 'main' into imagebind-model
dg845 a55faed
All modalities embeddings
EduardoPach fa77a40
Improving implementation
EduardoPach 5c8c223
Fix copies
EduardoPach bd3ac72
Improving conversion script
EduardoPach 12bd91b
Removed tokenizer
EduardoPach ca6fa03
Forward working
EduardoPach c618bcc
Format off and on
EduardoPach 835161c
Improvements on conversion script
EduardoPach f08dd8c
More improvements
EduardoPach 18dcde0
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 460fb00
Trying to make things write
EduardoPach 78ccd1f
Improving import and cos
EduardoPach 6e8407d
Fix copies
EduardoPach a83bebe
ImageBindFeatureExtractor
EduardoPach 0ee0902
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 7421c63
fix copies
EduardoPach 8af30b1
Improving tests
EduardoPach 99770c5
More improvements
EduardoPach 8a59421
Fixing tests
EduardoPach 3d3a273
Tests green
EduardoPach 8fcf36c
Improving consistency
EduardoPach cfe9da6
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach de7f84d
Removed speech dependency
EduardoPach 1c9b317
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 003ff10
Updated conversion script
EduardoPach a0ef219
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach df4c0e4
Improved ImageBindProcessor
EduardoPach 8d055f1
ImageBindProcessor working
EduardoPach 05ac8ba
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach c8ad793
Update docs and docstrings
EduardoPach 5b39d85
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 97c4bd5
ImageBindFeatureExtractor tests
EduardoPach d9c6c84
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 987f404
ImageBindProcessor tests
EduardoPach 709613c
Make tests green
EduardoPach 9fdcce4
Improve feature extractor
EduardoPach d0f788a
fix style and copies
EduardoPach 4d2dd20
fix style new
EduardoPach 2f2b511
nits
EduardoPach 45ce871
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 6fa3611
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 7f6684d
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach d04ab40
Update src/transformers/models/imagebind/__init__.py
EduardoPach bcd7626
Update tests/models/imagebind/test_modeling_imagebind.py
EduardoPach b0d5a9f
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 5a0a5ff
Fix tests
EduardoPach 670c2f5
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 37d8f84
Fix consistency
EduardoPach a0639fb
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 8c5cdf5
Update src/transformers/models/imagebind/configuration_imagebind.py
EduardoPach 0392b53
Addressed comments
EduardoPach 48671d3
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 0ed167f
Update src/transformers/models/imagebind/processing_imagebind.py
EduardoPach 4b112f0
Merge branch 'adding-imagebind' of https://github.com/EduardoPach/tra…
EduardoPach e6ffb8e
Fixed audio in processor
EduardoPach ad6bb42
Addressed more comments
EduardoPach ec8379d
Addressed more comments
EduardoPach 53683a4
Added comments to reduce clips for audio and videos
EduardoPach dab1877
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach b74d808
Update ImageBindConfig
EduardoPach ae0b489
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 55bd10f
Added video functionality to ImageBindImageProcessor
EduardoPach c151d6b
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach a9a5539
chore:add func and classes to get vid clips from user given paths
RUFFY-369 d1c33d0
chore:update uniform_chunk_sampling()
RUFFY-369 53fe080
chore:change chunk duration val and type
RUFFY-369 99306ab
chore:update uniform_temporal_subsample()
RUFFY-369 082be8b
chore:update video transforms and few nits
RUFFY-369 1d6c4ea
fix:bug in image processor call on video paths
RUFFY-369 229a779
fixed: math.ceil instead of int when getting clips from video
EduardoPach 8bea22a
Fixed copies
EduardoPach 64d6c38
chore:revert to original to test for unmatched outputs
RUFFY-369 558f544
chore:make transformers compliant and few nits
RUFFY-369 9314a57
style:make fixup
RUFFY-369 79c4089
fix:make fix copies
RUFFY-369 f64778d
chore:resolve necessary conflicts
RUFFY-369 8d717d0
Video is now matching
EduardoPach 02cb2ab
Merge remote-tracking branch 'imagebind/adding-imagebind' into imageb…
RUFFY-369 4d0edbf
resolve merge/change conflicts by pull
RUFFY-369 bc8821f
chore:make everything similar about files
RUFFY-369 fbbb108
test:add image processor tests
RUFFY-369 4099c8c
fix:failing image processor tests
RUFFY-369 2d4cb59
chore:add contributor name for video output matching and image proces…
RUFFY-369 a283626
test:add Processor kwargs and its test
RUFFY-369 04a9e07
fix:ProcessorTesterMixin test failures
RUFFY-369 4b7f5a8
fix:test failure for len of input ids
RUFFY-369 e2f3064
chore:add custom image and audio kwargs class and some nits
RUFFY-369 030027d
Merge pull request #2 from RUFFY-369/imagebind_hf
EduardoPach c4f19bb
fix: style
EduardoPach 8a53076
Merge remote-tracking branch 'upstream/main' into adding-imagebind
EduardoPach 12b9abf
fix: copies and import
EduardoPach 237954f
Update src/transformers/models/imagebind/processing_imagebind.py
RUFFY-369 43de0d7
Merge branch 'main' into adding-imagebind
RUFFY-369 6e6f581
chore:add suggested changes related to #31330
RUFFY-369 40a1170
style:make style;make quality
RUFFY-369 1bc9d74
chore:move assertions to modeling test file from ckpt conversion file…
RUFFY-369 3bf1476
style:make style
RUFFY-369 1d32a1d
chore:weights conversion file suggested changes
RUFFY-369 977179e
chore:add suggested changes for audio and images kwargs
RUFFY-369 3eec1eb
chore:typo changes
RUFFY-369 b284d4e
chore:remove use_square_size
RUFFY-369 fcb2fac
chore:add videos as input for processor as suggested
RUFFY-369 d7c1b70
chore:add suggested changes
RUFFY-369 2e7c000
chore:add suggested changes
RUFFY-369 fe32980
reverting previous config commit
RUFFY-369 eb1f17a
chore:decouple image_to_video from modeling as mentioned in suggested…
RUFFY-369 92a6ad1
chore:add more suggested changes
RUFFY-369 bc1b722
chore:refactoring _init_weights from suggested changes
RUFFY-369 8c8f563
Merge remote-tracking branch 'upstream/main' into adding-imagebind
RUFFY-369 6182b3e
chore:decouple build_attention_mask
RUFFY-369 be79290
chore:some more suggested changes
RUFFY-369 14f6cb5
chore: remove suggested changes
RUFFY-369 1b6716e
fix:test failures
RUFFY-369 ce49517
Merge remote-tracking branch 'upstream/main' into adding-imagebind
RUFFY-369 21f11cd
style:make style
RUFFY-369 ac95d27
chore: apply suggested changes
RUFFY-369 c2fb254
chore:address suggested changes
RUFFY-369 e853fc9
Merge remote-tracking branch 'upstream/main' into adding-imagebind
RUFFY-369 e0f741b
chore:suggested deprecate_kwarg for return_numpy
RUFFY-369 85337c7
chore:suggested nit for image_to_video
RUFFY-369 f9fae40
test:update atol due to observed flakyness
RUFFY-369 f878996
test:remove unwanted tests as they are already available with Process…
RUFFY-369 58e1c3a
chore: make suggested changes
RUFFY-369 e3353e5
chore:do nit suggested changes
RUFFY-369 76f99ab
test:add suggested assertion
RUFFY-369 17525ac
Merge remote-tracking branch 'upstream/main' into adding-imagebind
RUFFY-369 f893147
Merge remote-tracking branch 'upstream/main' into adding-imagebind
RUFFY-369 50e2ca3
chore:simplify weight conversion file with regex as suggested
RUFFY-369 3d3887b
style:make style
RUFFY-369 0951775
chore:remove unused func(from review suggestions)
RUFFY-369 e031e0d
chore: apply suggested changes
RUFFY-369 7ea5f59
chore: apply suggested changes
RUFFY-369 9d09258
chore: apply suggested changes
RUFFY-369 0adf14f
chore: apply suggested changes
RUFFY-369 40d50c9
chore: apply suggested changes
RUFFY-369 f8fa533
Merge remote-tracking branch 'upstream/main' into adding-imagebind
RUFFY-369 cfefa9b
chore:add suggested changes for single loop
RUFFY-369 30370f7
chore:apply suggested changes for abstract feature_size
RUFFY-369 106dfb0
chore:make few suggested changes
RUFFY-369 a637d59
Merge remote-tracking branch 'upstream/main' into adding-imagebind
RUFFY-369 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| <!--Copyright 2024 The HuggingFace Team. All rights reserved. | ||
|
|
||
| Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
| the License. You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
| an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
| specific language governing permissions and limitations under the License. | ||
| --> | ||
|
|
||
| # ImageBind | ||
|
|
||
| ## Overview | ||
|
|
||
| The ImageBind model was proposed in [ImageBind: One Embedding Space To Bind Them All](https://arxiv.org/abs/2305.05665) by Rohit Girdhar, Alaaeldin El-Nouby, Zhuang Liu, Mannat Singh, Kalyan Vasudev Alwala, Armand Joulin, Ishan Misra. | ||
| ImageBind is a multimodal joint embedding model for image/video, text, audio, depth, IMU, and thermal images. | ||
| For any input from these six modalities, it outputs the same-sized embedding that can be used for cross-modal and multimodal tasks. | ||
|
|
||
| The abstract from the paper is the following: | ||
|
|
||
| *We present ImageBind, an approach to learn a joint embedding across six different modalities - images, text, audio, depth, thermal, and IMU data. We show that all combinations of paired data are not necessary to train such a joint embedding, and only image-paired data is sufficient to bind the modalities together. ImageBind can leverage recent large scale vision-language models, and extends their zero-shot capabilities to new modalities just by using their natural pairing with images. It enables novel emergent applications 'out-of-the-box' including cross-modal retrieval, composing modalities with arithmetic, cross-modal detection and generation. The emergent capabilities improve with the strength of the image encoder and we set a new state-of-the-art on emergent zero-shot recognition tasks across modalities, outperforming specialist supervised models. Finally, we show strong few-shot recognition results outperforming prior work, and that ImageBind serves as a new way to evaluate vision models for visual and non-visual tasks.* | ||
|
|
||
| This model was contributed by [EduardoPacheco](https://huggingface.co/EduardoPacheco) and [ruffy369](https://huggingface.co/ruffy369) and [dg845](https://huggingface.co/dg845) and [shehan97](https://huggingface.co/shehan97). | ||
| The original code can be found [here](https://github.com/facebookresearch/ImageBind). | ||
|
|
||
| ## Usage tips | ||
|
|
||
| - ImageBind can be used for multi-modality similarity and zero-shot tasks. | ||
| - Currently only Vision (image and video), Audio and Text are supported. | ||
| - One can use [`ImageBindProcessor`] to prepare all or pairs of the available modalities. | ||
| - [`ImageBindModel`] `forward` expects only one pair of modalities where one of those MUST be vision modality. | ||
| - If interest only on the modalities embeddings one can use [`ImageBindModel`] `get_xxx_features` method or the appropriate `ImageBindXxxModelWithProjection` | ||
| - As ImageBind vision and text encoders were frozen during training and are initialized with OpenCLIP ViT-H if one has an application using this model the addition of other modalities by including other encoders would be possible. | ||
|
|
||
| Here's one example of how to get the embeddings for images, text and audios (this example requires `torchaudio`!) | ||
|
|
||
| ```python | ||
| import torch | ||
| import torchaudio | ||
| from datasets import load_dataset | ||
| from transformers import ImageBindModel, ImageBindProcessor | ||
|
|
||
| ds = load_dataset("EduardoPacheco/imagebind-example-data", split="train") | ||
| images = ds["image"] | ||
| text = ds["text"] | ||
| audios = ds["audio"] # It's a dict with keys -> array and sampling_rate | ||
| audios = [ | ||
| torchaudio.functional.resample( | ||
| torch.from_numpy(audio["array"]), | ||
| orig_freq=audio["sampling_rate"], | ||
| new_freq=16000 | ||
| ).numpy() | ||
| for audio in audios | ||
| ] | ||
|
|
||
| model = ImageBindModel.from_pretrained("EduardoPacheco/imagebind-huge") | ||
| processor = ImageBindProcessor.from_pretrained("EduardoPacheco/imagebind-huge") | ||
|
|
||
| inputs = processor(text=text, images=images, audios=audios, padding=True, return_tensors="pt") | ||
|
|
||
| with torch.no_grad(): | ||
| audio_embeds = model.get_audio_features(input_features=inputs.input_features) | ||
| image_embeds = model.get_image_features(pixel_values=inputs.pixel_values) | ||
| text_embeds = model.get_text_features(input_ids=inputs.input_ids, attention_mask=inputs.attention_mask) | ||
|
|
||
| # we can compute probs to use for retrieval or zero-shot workflows. | ||
| probs_image_text = (image_embeds @ text_embeds.T).softmax(dim=-1) | ||
| probs_text_audio = (text_embeds @ audio_embeds.T).softmax(dim=-1) | ||
| probs_image_audio = (image_embeds @ audio_embeds.T).softmax(dim=-1) | ||
| ``` | ||
|
|
||
| ## ImageBindConfig | ||
|
|
||
| [[autodoc]] ImageBindConfig | ||
| - from_text_vision_configs | ||
|
|
||
| ## ImageBindTextConfig | ||
|
|
||
| [[autodoc]] ImageBindTextConfig | ||
|
|
||
| ## ImageBindVisionConfig | ||
|
|
||
| [[autodoc]] ImageBindVisionConfig | ||
|
|
||
| ## ImageBindAudioConfig | ||
|
|
||
| [[autodoc]] ImageBindAudioConfig | ||
|
|
||
| ## ImageBindImageProcessor | ||
|
|
||
| [[autodoc]] ImageBindImageProcessor | ||
| - preprocess | ||
|
|
||
| ## ImageBindFeatureExtractor | ||
|
|
||
| [[autodoc]] ImageBindFeatureExtractor | ||
|
|
||
| ## ImageBindProcessor | ||
|
|
||
| [[autodoc]] ImageBindProcessor | ||
|
|
||
| ## ImageBindModel | ||
|
|
||
| [[autodoc]] ImageBindModel | ||
| - forward | ||
| - get_text_features | ||
| - get_image_features | ||
| - get_audio_features | ||
|
|
||
| ## ImageBindTextModel | ||
|
|
||
| [[autodoc]] ImageBindTextModel | ||
| - forward | ||
|
|
||
| ## ImageBindTextModelWithProjection | ||
|
|
||
| [[autodoc]] ImageBindTextModelWithProjection | ||
| - forward | ||
|
|
||
| ## ImageBindVisionModel | ||
|
|
||
| [[autodoc]] ImageBindVisionModel | ||
| - forward | ||
|
|
||
|
|
||
| ## ImageBindVisionModelWithProjection | ||
|
|
||
| [[autodoc]] ImageBindVisionModelWithProjection | ||
| - forward | ||
|
|
||
| ## ImageBindAudioModel | ||
|
|
||
| [[autodoc]] ImageBindAudioModel | ||
| - forward | ||
|
|
||
| ## ImageBindAudioModelWithProjection | ||
|
|
||
| [[autodoc]] ImageBindAudioModelWithProjection | ||
| - forward | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -116,6 +116,7 @@ | |
| idefics, | ||
| idefics2, | ||
| idefics3, | ||
| imagebind, | ||
| imagegpt, | ||
| informer, | ||
| instructblip, | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
molbap marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Copyright 2024 The HuggingFace Team. All rights reserved. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
| from typing import TYPE_CHECKING | ||
|
|
||
| from ...utils import _LazyModule | ||
| from ...utils.import_utils import define_import_structure | ||
|
|
||
|
|
||
| if TYPE_CHECKING: | ||
| from .configuration_imagebind import * | ||
| from .feature_extraction_imagebind import * | ||
| from .image_processing_imagebind import * | ||
| from .modeling_imagebind import * | ||
| from .processing_imagebind import * | ||
| else: | ||
| import sys | ||
|
|
||
| _file = globals()["__file__"] | ||
| sys.modules[__name__] = _LazyModule(__name__, _file, define_import_structure(_file), module_spec=__spec__) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.