2024. 5. 2. 23:22ㆍDevelopers 공간 [SOTA]
- Paper : https://arxiv.org/pdf/2402.17113
- Authors
- Lvmin Zhang et al, Stanford Univ., arxiv’24
- ControlNet 저자
- Main Idea
- pre-trained LDM을 활용해 transparent 이미지를 생성하도록 합니다.
- Task1. 하나의 transparent 이미지 생성
- Task2. multiple transparent layers
- 위 Task2 모델에서는 Shared Attention 메커니즘을 활용해 레이어간의 coherent하도록 학습합니다.
- HITL collection scheme을 활용해 데이터를 구축했습니다.
- Tasks : Transparent Image Generation (Unconditional, Conditional)
- Results : User case
- pre-trained LDM을 활용해 transparent 이미지를 생성하도록 합니다.
<구성>
1. Problem
a. Image Matting
b. No layer-based DM
2. Approach
a. Latent Transparency Encoder-Decoder
b. Diffusion Model
c. Dataset Preparation
3. Results
a. Setting
b. Qualitative Results
c. Ablation Study
d. vs Ad-hoc method
4. How to use
a. ComfyUI
b. SD Web UI
글효과 분류1 : 논문 내 참조 및 인용
글효과 분류2 : 폴더/파일
글효과 분류3 : 용어설명
글효과 분류4 : 글 내 참조
글효과 분류5 : 글 내 참조2
글효과 분류6 : 글 내 참조3
1. Problem
기존에는 생성된 이미지 혹은 이미지 자체를 Matting하는 기법들은 이미 많이 쓰이고 발전되고 있었습니다.
하지만 본 논문은 생성된 이미지를 Matting하는 Solution이 아닌, 생성될 때 부터 alpha채널을 가지고 생성을 진행하는 방법을 제안하며, 이 것이 더욱 선호된다고 주장하고 있습니다.
시작하기에 앞서 기존의 Image Matting 기법에 대해 간단히 설명한 후, 왜 이전에는 이런 Transparent한 이미지를 생성하는 것이 불가능했는지에 대한 배경을 소개하겠습니다.
a. Image Matting
natural 이미지에서 foreground와 background를 분리하는 Matting 기법은 ad-hoc한 솔루션 이었습니다.
** ad-hoc Solution (≒하드코딩): 원래는 라틴어로, “for this particular purpose”라는 뜻을 가집니다. 즉, 특정 상황에서만 정답이 되는 solution을 의미하는 프로그래밍 입니다.
예를 들어 위의 경우 생성 이후에 matting을 하는 경우, 특정 생성에 맞게 matting이 될 것이기 때문에 general한 solution이 아닌 ad-hoc solution이라고 할 수 있습니다.
Image Matting은 [0.0~1.0]의 opacity(투명도)를 찾아 foreground와 background간의 비율을 찾는 alpha matting을 통해 진행됐습니다. 즉, opacity가 1이면 완벽한 foreground이며, 0이면 완벽한 background입니다.
** alpha 채널은 [0.0, 1.0] 혹은 [0, 255]의 값을 가지며, 0.0을 가지는 경우 완벽하게 transparent(투명)하며, 1.0을 가지면 opaque(불투명)합니다.
이를 위한 기존의 전통적인 방법으로는, 근접해 있는 image pixel 간의 correlation을 통해 찾아내는 color sampling-based 방법이나, 근접 픽셀 간의 similarity를 파악하는 affinity matrix를 계산하는 affinity-based 방법을 활용했습니다.
** affinity matrix : 데이터의 point간 유사성을 표현하는 유사도 행렬로, diagonal은 “자기 자신과의 유사도”이므로 항상 가장 높은 값을 가집니다.
이후에는 trimap, scribble 같은 보조 input을 활용해 이런 문제를 해결하려고 했는데, MatAny에 따르면 trimap을 얻기 위한 높은 인건비 때문에 문제가 있다고 합니다. 따라서 최근엔 SAM 등 segmentation 모델을 활용해 이런 trimap을 얻어내는 방법으로 이어지기도 했습니다.
** Trimap : 이미지를 foreground, background, unknown으로 나눈 hint map
** [MatAny] Matte Anything: Interactive Natural Image Matting with Segment Anything Models (arxiv’23)
** [MAM] Matting Anything (arxiv’23)
b. No layer-based DM
다양한 visual content를 edit하는 소프트웨어나 워크플로우는 대부분 layer-based임에도 불구하고, layer content를 generation하는 방법은 많지 않다고 합니다.
이에 대해 본 논문에서는 두가지 원인을 이야기합니다.
- 학습할 데이터가 적다고 합니다. 대부분의 transparent한 이미지 데이터는 굉장히 적으며, 가능한 데이터의 경우 유료이거나 제한된 접근이 필요합니다.
- 현재 존재하는 생성 모델에서는 transparent한 이미지를 data representation으로 표현하기 어렵다고 합니다. 예를 들어 SD와 같은 모델의 경우, latent space상에서 어떻게 표현하는지에 따라 성능이 민감하므로 활용하기 어렵다고 합니다.
이에 따라 본 논문은 transparent를 이미지를 생성하거나, multi-layered transparent 이미지를 생성하기 위해 alpha 채널의 transparency를 latent manifold에서 다루는 “latent transparency”접근을 제안합니다.
2. Approach
먼저 데이터로 활용할 이미지의 차원은 아래와 같습니다. $I_c$는 기존의 RGB채널을 가진 이미지를 의미하며, $I_\alpha $는 alpha채널을 의미합니다.
$$I_t=[I_c,I_\alpha ]\in \mathbb{E}^{h\times w\times (3+1)}$$
이 때, 사용할 이미지의 $I_\alpha $ 값이 0인 경우 color를 조작하더라도 이미지의 결과에 영향을 주지않으므로 “undefined pixel"이라고 부릅니다.
하지만 네트워크는 이미지의 edge부분에서 굉장히 high-frequency패턴을 제공하는 경향이 있는데, undefined pixel들로 인해 쓸데없는 edge들을 제공할 확률이 높기 때문에, 데이터로 활용할 때 아래와 같이 undefined pixel이 아닌 $I_c$에 gaussian filter $\phi ()$를 iterative하게 처리해준 후에 사용합니다.
$$\left\{\begin{matrix}
\phi&(I_c)_p&,if(I_a)_p>0\\
&(I_c)_p&,otherwise
\end{matrix}\right.$$
** Gaussian Filter에 대해 궁금하신 분들은 아래 더보기를 참조하세요
------------------------------------------------------
<Gaussian Filter>
원래 평균필터(Average Filter)는 필터의 모든 값이 1의 같은 값을 가지며, 해당 필터 내의 값에 평균을 취함으로써 이미지에 적용할 시 Blurring하는 효과를 가집니다.
하지만 이는 대상 픽셀과, 주변 픽셀의 차이를 구분하지 못하므로, gaussian 함수를 활용해 대상 pixel의 값이 가장 크고 주변으로 갈수록 작아지는 특징을 가지는 Guassian Filter를 활용합니다.
결과적으로 아래와 같이 이미지를 blurring할 때 똑같이 사용하지만, 대상 픽셀에 가까울 수록 blurring효과가 더 크도록 할 수 있습니다.
------------------------------------------------------
이때 guassian filter는 13x13 커널을 활용해 64번 iterative하게 진행했으며, 위 식과 같이 0이상의 값일 때만 사용해 전체가 undefined pixel 비슷해지도록 만들어주었습니다.
이렇게 처리된 $I_c$를 “padded RGB 이미지”라고 부릅니다.
a. Latent Transparency Encoder-Decoder
위에서 다루었던 $I_\alpha $와 $I_c$는 아래식과 그림과 같이 두가지 VAE encoder $\varepsilon^*_{sd}$와 $\varepsilon $으로 처리된 후 더해집니다.
$$\begin{matrix}
x_\epsilon &=& \varepsilon([I_c,I_\alpha])\\
x&=&\varepsilon^*_{sd}(I_c*I_a)\\
x_a&=&x+x_\epsilon
\end{matrix}$$
먼저, $\varepsilon^*_{sd}$는 $I_c$와 $I_\alpha $를 곱한 상태로 기존의 frozen Stable Diffusion의 VAE encoder 그대로 통과해 latent인 $x$를 만들어냅니다.
다음으로, latent transparency encoder $\varepsilon $는 $I_c$와 $I_\alpha $를 concat한 형태로 4개의 채널을 가진 이미지를 만들고, 아래 그림과 같이 직접 학습합니다. 결과적으로 기존의 latent에서 transparency를 반영한 latent offset인 $x_\epsilon $를 만들어냅니다.
** 결국 이 latent offset $x_\epsilon $가 이 논문에서 강조하는 "latent transparency"를 반영하고 있는 핵심이라고 합니다.
이렇게 처리된 latent들을 각각 $x$, $x_\epsilon $라고 부르는데, 결과적으로 이둘이 합쳐 adjusted latent $x_a$를 이룹니다.
다음으로 이제 adjusted latent $x_a$는 아래 식과 같이 두가지 방법으로 decode하는데 사용됩니다.
$$\begin{matrix}
\hat{I} &=& \mathcal{D}^*_{sd}(x_a)\\
[\hat{I}_c, \hat{I}_\alpha]&=&\mathcal{D}(x_a, \hat{I})
\end{matrix}$$
먼저 $\mathcal{D}^*_{sd}$의 경우 기존의 frozen Stable Diffusion의 VAE decoder와 같으며, $\hat{I}$를 만들어 냅니다. 이는 아래와 같은 두가지 용도로 활용됩니다.
- 뒤에 나올 $\mathcal{D}$의 Input으로 활용
- “얼마나 latent transparency encoder가 기존의 기능을 망가트렸는지”를 측정해줄 지표로 활용
** Loss에서 활용됩니다.
또한 latent transparency decoder $\mathcal{D}$는 기존 Stable Diffusion의 VAE encoder와 decoder를 합쳐 UNet구조를 가지며, 직접 학습합니다.
구체적으로 살펴보면, 앞서 만들었던 $\hat{I}$를 input으로 활용해 VAE encoder를 통해 projection하고, 이 때 latent $x_a$가 middle block에서 더해진 후, VAE decoder를 통해 $\hat{I}_c$와 $\hat{I}_\alpha$를 만들어냅니다.
결과적으로 위 그림과 같이 alpha채널이 있는 $\hat{I}_\alpha$와 RGB채널이 있는 $\hat{I}_c$를 만들어 냅니다.
latent transparency encoder $\varepsilon $와 latent transparency decoder $\mathcal{D}$를 학습하기 위한 Loss는 아래와 같습니다.
** 이 때 ||~||의 경우 단순한 L2 norm distance (mean squared error)를 의미합니다.
$$\begin{matrix}
L_{identity}&=&\left \| I-\hat{I} \right \|_2\\
L_{recon}&=&\left \| I_c-\hat{I}_c \right \|_2+\left \| I_a-\hat{I}_a \right \|_2\\
L_{disc}&=&\mathbb{L}_{disc}([\hat{I}_c,\hat{I}_a])\\
L&=&\lambda _{recon}L_{recon}+\lambda _{identity}L_{identity}+\lambda _{disc}L_{disc}
\end{matrix}$$
먼저, $L_{identity}$의 경우, $\varepsilon^*_{sd}$의 Input으로 활용되었던 $I_c$와 $I_\alpha $를 곱한 상태의 이미지 $I$와, latent $x_a$의 $\mathcal{D}^*_{sd}$결과인 $\hat{I}$간의 차이를 측정합니다.
즉, 앞서 만들었던 latent인 $x_a$의 latent distribution이, frozen Stable Diffusion의 VAE encoder를 활용한 latent distribution과 비슷해야만 성능이 유지된다고 합니다. 이것을 비교하기 위해 본논문에서 만든 latent $x_a$를 직접 decode한 결과와 비교하는 직접적인 방법을 취했습니다.
결과적으로 $L_{identity}$를 통해 “harmfulness”를 측정하고, 이 값이 큰 경우 transparency 정보를 담은 latent offset $x_\epsilon $이 기존 SD의 encoder-decoder의 reconstruction기능을 감소시켰는지 판단할 수도 있습니다.
다음으로는, VAE encoder-decoder를 학습하기 위한 Loss이지만, Diffusion 모델 전체를 학습할 때와 같이 최종적으로 Reconstruction이 얼마나 잘 되었는지를 측정하기 위한 Reconstruction Loss $L_{recon}$과 Discriminator Loss $L_{disc}$를 활용합니다.
--------------------------------------------------------------
<Discriminator Loss>
기존의 SD의 Discrimiantor를 조금 자세히 설명하자면 아래 식과 같습니다.
$$\mathbb{L}_{disc}(z)=relu(1-D_{disc}(z))$$
이때의 discriminator 네트워크의 자세한 구조는 아래와 같습니다.
- 5개의 [Convolution-Normalization-Silu] Layer
512x512x3 → 512x512x64 → 256x256x128 → 128x128x256 → 64x64x1 - 마지막 Classification layer
patch-wise하게 real/fake를 판단하기 위한 classification layer(normalization, activation 없음)
--------------------------------------------------------------
위 Loss식의 weighting 파라미터인 $\lambda _{recon}$는 1.0, $\lambda _{identity}$도 1.0, $\lambda _{disc}$는 0.01를 default로 사용했다고 합니다.
b. Diffusion Model
샘플링 과정에서는 latent $x_a$가 위와 같은 과정으로 학습된 Latent Transparency decoder를 통해 alpha 채널 $\hat{I}_\alpha$와 RGB채널 $\hat{I}_c$를 만들어 낼 것인데, 위에서 만들어진 latent $x_a$는 어떤 네트워크로부터 생성해낼까요?
그것을 이제부터 학습해야 합니다.
Step1. Single transparent image
위에서 만들어낸 latent들을 기반으로 기존의 LDM을 직접적으로 fine-tune합니다.
즉, 위에서 구한 latent $x_a$는 transparent 이미지 정보를 가지고 있으므로, 우리가 fine-tune할 DM은 아래 그림과 같이 transparent 이미지를 생성할 수 있는 모델을 학습하는 것입니다.
이 때 Loss는 기존의 SD와 같이 아래와 같으며, 이렇게 학습된 모델을 base model이라고 부릅니다.
$$L=\mathbb{E}\left [ \left \| \epsilon -\epsilon _\theta (x_t,t,c_t) \right \|_2 \right ]$$
Step2. Multiple layers
이번엔 base model을 여러개의 layer를 생성할 수 있는 모델로 바꾸려고 합니다.
먼저 예를 들어 foreground를 생성하는 모델과 background를 생성하는 모델을 독립적으로 학습하는 경우, 각각의 loss는 아래와 같으며, fine-tune을 위해 각각 LoRA를 활용합니다. 이때, $\theta _f$와 $\theta _b$는 각각의 LoRA 파라미터를 의미합니다.
$$\begin{matrix}
L_f&=&\mathbb{E}\left [ \left \| \epsilon _f-\epsilon _{\theta , \theta _f}(x_{f,t},t,c_t) \right \|_2 \right ]\\
L_b&=&\mathbb{E}\left [ \left \| \epsilon _b-\epsilon _{\theta , \theta _b}(x_{b,t},t,c_t) \right \|_2 \right ]
\end{matrix}$$
이번엔 foreground와 background가 coherent하게 생성하도록 학습하기 위해 두 네트워크의 정보를 섞을 것인데, 이때 Attention Sharing방법을 활용합니다.
자세히 설명하자면, 두 모델이 각각 생성해야 할 noise는 두 모델의 output을 concat한 $\epsilon _{fb}=[\epsilon _{f},\epsilon _{b}]$입니다. 이때, 두개의 모델의 Attention을 sharing해 나온 $\epsilon _{\theta , \theta _f, \theta _b}$를 아래의 Loss로 학습하는 것입니다.
$$L_{layer}=\mathbb{E}\left [ \left \| \epsilon _{fb}-\epsilon _{\theta , \theta _f, \theta _b}(x_{f,t},x_{b,t}, t,c_t) \right \|_2 \right ]$$
즉, 두 모델은 실제로는 각각 다른 네트워크를 가지지만 두 모델의 Attention을 공유하기 때문에 하나의 네트워크처럼 보이며, 각각의 네트워크의 Attention에 들어갈 {key,query,value}를 concat해 공유된 Attention을 통과시켜 줍니다.
Step3. Conditional generation
또한 condition을 통해 layer를 생성하는 모델로 확장도 가능한데, 먼저 가능한 여섯가지의 conditioned generation task를 나열해보겠습니다.
- a. foreground를 활용해 background를 생성
- b. background를 활용해 foreground를 생성
- c. foreground를 활용해 blended를 생성
- d. background를 활용해 blended를 생성
- e. (foreground, blended)를 활용해 foreground를 제거
- f. (background, blended)를 활용해 background를 제거
먼저 a와 b를 살펴보면, 학습은 간단하게 아래의(위에서 이미 보았던) objective에서 간단하게 몇가지를 수정해 condition이 가능하도록 할 수 있습니다.
$$L_{layer}=\mathbb{E}\left [ \left \| \epsilon _{fb}-\epsilon _{\theta ,\theta _f, \theta _b}(x_{f,t},x_{b,t}, t,c_t) \right \|_2 \right ]$$
"a. foreground를 활용해 background를 생성"를 예로 설명하겠습니다.
위 Loss를 계산할 때, $\epsilon _f$를 0으로 한다면, foreground는 계속해서 noisy latent가 아닌 clean latent를 가지게 될 것이고, foreground를 denoise하지 않게 됩니다. 하지만 background는 denoise되어 background를 만들게 될 것입니다.
** 논문에는 나와 있지 않지만 필자의 생각으로는, LDM과 CDM에서 condition 이미지를 input에 initial noise와 함께 concat하여 제공하는 것과 같이, 샘플링 시에 foreground 네트워크에 initial noise로 초기 이미지를 condition으로 넣어줄 것 같습니다.
(저는 처음보는 conditioning 기법입니다만..)
이렇게 foreground를 condition으로 하는 background 생성 네트워크를 학습시킬 수 있습니다.
또한 blended 이미지와 연관된 나머지 task인 c(그림 a), d(그림c), e(그림b), f(그림d)의 경우 다른 형태로 만들어줄 수 있습니다.
"c. foreground를 활용해 blended를 생성"(위 그림중 (a))을 예로 설명하겠습니다.
위의 a,b 컨디션을 줄때와 다른 것은, 앞서 언급했듯이 condition을 특이하게도 "다른 네트워크"의 noise를 clean하게 바꿔준 것과 다르게, 기존 LDM혹은 CDM과 같이 zero-initialized 된 채널을 UNet에 추가해 condition으로 활용합니다.
즉 위의 경우, initial noise에 0으로 초기화된 channel을 추가한 후에, 해당 채널에 latent transparency VAE를 통해 나온 foreground의 encoded latent를 넣어줍니다.
결과적으로 output은 blended 이미지의 noise가 나오게되겠죠.
c. Dataset Preparation
앞서 이 분야에서 Layer 기반의 생성이 부족한 이유가 데이터가 부족하다고 언급했던 것을 기억하실 겁니다.
따라서 아래와 같이 데이터를 준비하는 과정을 상세히 보였습니다.
a. Base Dataset : {text, transparent image} pair
먼저, transparent image를 생성하기 위한 dataset을 준비해보겠습니다. HITL방법을 활용해 transparent 이미지를 수집했습니다.
** HITL(Human-In-The-Loop) : Labeling에 있어서 디테일한 부분들은 사람이 직접 검수 및 조정 등의 interaction을 통해 정확하게 학습이 가능하도록 하는 positive feedback의 일종입니다.
아래와 같은 순서로 데이터셋을 준비합니다.
- 먼저, 20k의 transparent PNG 이미지를 준비한 후, 기존의 네트워크를 학습시킵니다.
(위 과정에서 만들었던 SDXL의 새로운 latent transparency enc-dec를 학습한 후, DM을 학습) - 다음으로, 아래와 같은 과정을 25 rounds 반복합니다.
초기의 20k가 한 번의 round당 1k의 이미지가 생겨 최종적으로 45k개의 이미지가 됩니다.
- Step1. LAIONPOP에서 나온 random prompt를 통해, 10k의 random sample을 생성합니다.
- Step2. 10k 중 1k의 샘플을 manual하게 직접 선택해 데이터셋에 추가합니다.
(방금 추가된 데이터셋은 다음 Step3 학습에 2배 높은 확률로 등장할 예정입니다) - Step3. 기존의 네트워크를 학습시킵니다.
(위 과정에서 만들었던 SDXL의 새로운 latent transparency enc-dec를 학습한 후, DM을 학습)
- 모든 round를 반복한 후, 학습한 모델로 Human Interaction없이 5M의 샘플 pair를 생성합니다.
- 위 결과를 Sorting한 후, 1M의 샘플을 선택합니다.
- 이 때 Sorting에 사용한 Metric은 LAION Aesthetic threshold(5.5)와 clip score입니다.
- 이 과정에서 transparent pixel이나 visible pixel이 아예 없는 샘플들은 삭제됩니다.
- 위 1M의 샘플을 오픈소스 Multi-modal GPT인 LLAVA를 통해 captioning합니다.
** LLAVA : Visual instruction tuning(NIPS’23) - 최종적으로 얻은 1M의 샘플을 통해 네트워크를 재학습시킵니다. (15k iterations)
(위 과정에서 만들었던 SDXL의 새로운 latent transparency enc-dec를 학습한 후, DM을 학습)
** 위 내용 중 LAION Aesthetic threshold와 LLAVA에 대해 추가로 궁금하신 분들은 아래 더보기를 참조하세요
------------------------------------------------------
<LAION Aesthetic threshold(Aesthetic Score)>
LAION 5B 데이터셋을 소개한 블로그(https://laion.ai/blog/laion-aesthetics/)를 보면, LAION-Aesthetics_Predictor V2이라는 모델을 사용해 아래와 같이 subset을 만들었다고 하고 있습니다.
- 1,2B image-text pairs with predicted aesthetics scores of 4.5 or higher
- 939M image-text pairs with predicted aesthetics scores of 4.75 or higher
- 600M image-text pairs with predicted aesthetics scores of 5 or higher
- 12M image-text pairs with predicted aesthetics scores of 6 or higher
- 3M image-text pairs with predicted aesthetics scores of 6.25 or higher
- 625K image-text pairs with predicted aesthetics scores of 6.5 or higher
실제로 LAION-Aesthetics_Predictor V2이라는 모델은 CLIP과 MLP를 합쳐 만든 모델로 Aesthetic score를 predict하는 모델입니다. 아래와 같이 데모를 돌려보면 aesthetic score가 나오는 것을 볼 수 있습니다.
**https://github.com/christophschuhmann/improved-aesthetic-predictor
------------------------------------------------------
------------------------------------------------------
<Pre-trained Image Representation Model>
보통 Image의 Representation을 Text를 활용해 학습하기 위해 아래와 같이 다양한 방법을 활용합니다. 이들은 보통 세가지 용도로 활용되는데, 모델의 형태에 따라 사용되는 방법이 다릅니다.
- Embedding : Text Encoder로 활용해 Text의 정보가 이미지와 얼마나 연관성 있는지에 대한 prior로 활용합니다.
ex) CLIP, DINOv2
** DINOv2: Learning Robust Visual Features without Supervision(arxiv’23) - Captioning : Image에 대한 captioning 등 text정보를 얻기 위해 사용합니다.
ex) LLava, BLIP, ALBEF, Git, Beit-3, Coca
** [ALBEF] Align before fuse: Vision and language representation learning with momentum distillation (NIPS’21)
** [Git] Git: A generative image-to-text transformer for vision and language (arxiv’22)
** [Beit-3] Image as a foreign language: Beit pretraining for all vision and vision-language tasks(arxiv’22)
** [Coca] Coca: Contrastive captioners are image-text foundation models (arxiv’22) - Metric : Image와 Text의 정보를 가진 embedding을 활용해 결과를 분석하는 metric으로 활용합니다.
ex) CLIP-score, BLIP-VQA, DINO, TIFA
** [DINO] Emerging Properties in Self-Supervised Vision Transformers
** [TIFA] TIFA: Accurate and Interpretable Text-to-Image Faithfulness Evaluation with Question Answering (ICCV'23)
1. CLIP (Contrastive Language-Image Pre-training)
Learning Transferable Visual Models From Natural Language Supervision (arxiv’21)
CLIP은 Natural Language를 통해 image representation learning을 하는 방법입니다.
기존에 NLP분야에서는 task-agnostic(task와 무관한)한 구조를 만들기 위해 수많은 데이터로 pre-training을 하고, downstream task를 위한 zero-shot transfer를 가능하게 할 수 있었다고 합니다.
하지만 Computer Vision 분야에서는 이를 위한 시도 없이, 라벨링 된 데이터셋에서 pre-terain하는 것이 관행이었습니다. 따라서 이분야에 대해 한번 살펴보겠습니다.
a. Image Representation for Natural Language
image representation을 학습하기 위해서, 기존에 image representation을 classifier의 weight space에서 manifold 학습하는 방법에서 시작해, VirTex(transformer-based Language Modeling), ICMLM(masked language modeling), Con-VIRT(contrastive objectives)와 같은 모델들의 등장으로 image representation을 학습하면서 text로 표현하는 것이 가능해보이기도 했습니다.
** VirTex : Virtex: Learning visual rep- resentations from textual annotations (arxiv’20)
** ICMLM : Learning visual representations with caption annotations (arxiv’20)
** Con-VIRT : Contrastive learning of medical visual representations from paired images and text (arxiv’20)
하지만 이들은 20만개의 이미지만을 이용하는 등 scale이 작게 학습되어 최신 image representation learning결과보다 성능이 많이 떨어집니다. 따라서 Image representation learning에 natural language를 활용한 supervision은 많지는 않습니다.
b. Weakly Supervised Model
위와 같이 성능이 떨어지기는 하지만 BiT혹은 ViT같은 weakly supervised pre-trained 모델의 등장으로 transfer를 위한 성능이 가능할 것 처럼 보이기도 합니다.
** BiT :Big Transfer (BiT): General Visual Representation Learning(arxiv’19)
** ViT : An image is worth 16x16 words: Transformers for image recognition at scale (arxiv’20)
이들은 수십억개의 이미지를 활용해 학습되었지만, 제한된 클래스를 가지고 softmax classifier를 활용해 학습하기 때문에 dynamic한 output을 얻을 수 없어 Natural Language가 가진 넓은 표현력을 가질 수 없습니다. 따라서 이로 인해 zero-shot 능력과 같은 flexibility가 줄어들었다고 합니다.
본논문은 위 둘 간의 gap을 줄이기 위한 방법으로 아래의 contribution을 가집니다.
- 데이터 scale을 위해 400M개의 (image,text) pair의 WIT(Web Image Text) 데이터셋을 만들었습니다. 이들은 class balance를 위해 각각 20,000 pair 정도를 가집니다.
- ConVIRT의 simplified version을 scratch부터 학습했으며, 구조는 아래 그림과 같습니다.
- Image Encoder : ResNet, ViT
- ResNet : Resnet-50, ResNet-101, ResNet-50x4, ResNet-50x16, ResNet-50x64
** xN은 EfficientNet-style로 모델 스케일링을 진행함을 의미합니다. - ViT : ViT-B/32, ViT-B/16, ViT-L/14
- ResNet : Resnet-50, ResNet-101, ResNet-50x4, ResNet-50x16, ResNet-50x64
- Text-Encoder : Sparse Transformer
- Image Encoder : ResNet, ViT
- 이 때, exact word를 예약하는 것이 아닌, 어떤 text가 이미지에 pair되기 좋은지를 학습했습니다.
- 또한 contrastive representation learning을 통해 예측 대상에 대해 더 잘 학습할 수 있도록 했습니다. ** contrastive representation learning : self-supervised representation learning의 방식 중 하나로, 저차원 공간에서 유사한 데이터는 가깝게, 다른 데이터는 멀리 떨어져 있도록 학습하는 방법입니다. 따라서 동일한 예측 대상에 대해서는 더 좋은 표현을 나타낼 수 있습니다.
CLIP은 텍스트와 이미지간의 joint embedding space를 가지기 때문에, 둘 간의 alignment를 측정할 수 있는 score로 활용되기도 합니다.
** CLIPScore: A Reference-free Evaluation Metric for Image Captioning (arxiv'21)
이들은 아래와 같은 variation이 존재합니다.
- CLIP Similarity : 텍스트에 대해 이미지를 생성했을 때, 이미지의 변화량이 텍스트의 변화량과 얼마나 비슷한지 확인할 수 있는 metric입니다.
$$S:=\frac{<\Delta I,\Delta T>}{||\Delta I||||\Delta T||}$$ - Visual CLIP Similarity : Image(Input → Output)이 Target(Input → Output)과 얼마나 비슷한지를 의미
- Image CLIP Similarity : Image(Input → Output)에서 Output이 Input과 얼마나 비슷한지를 의미
- CLIP-I : Image CLIP Similarity의 평균
2. BLIP (Bootstrapping Language-Image Pre-training)
BLIP : Bootstrapping Language-image pre-training for unified vision-language understanding and generation (ICML’22)
BLIP-2: Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models (arxiv’23)
VLP(Vision-Language Pre-training)은 vision-language task에서 성능을 보이고 있지만, understanding-based task 혹은 generation-based task 중 하나에서만 성능을 보였습니다. 또한, noisy한 dataset을 scale up하는 방법은 supervision에 있어 sub-optimal이기 때문에 두 task 모두에 대해 transfer learning이 가능한 flexibity를 줄 수 있는 BLIP을 보입니다.
BLIP의 구조는 아래와 같습니다.
- Image Encoder : ViT
- Text Encoder : BeRT + [CLS]
** [CLS] : 문장을 요약하는 토큰 - Image-grounded Text encoder : BeRT + Cross Attention layer + [Encode]
** [Encode] : image-text pair의 multimodal representation - Image-grounded Text decoder : BeRT + Cross Attention layer + [Decode]
** 위 Bert의 bi-directional self-attention을 causal self-attention으로 대체합니다.
** [Decode] : 문장의 시작을 알리는 토큰입니다.
BLIP은 아래와 같은 특징을 가집니다.
- Multimodal mixture of Encoder-Decoder (MED) : 위 그림과 같이 image와 text를 각각 encode하는 unimodal encoder로 동작할 수도 있고, visual 정보를 섞어 text를 활용하는 image-grounded text encoder/decoder로도 동작할 수 있습니다. 아래와 같이 objectives는 세가지를 가지고 있습니다.
- image-text contrastive learning(ITC) : vision과 language representation을 align하기 위해 Unimodal Encoder에서 사용되는 loss
- image-text matching (ITM) : image-text pair간의 positive/negative pair를 구분해냄으로써 vision-language interaction을 모델링 하기 위해 image-grounded text encoder에서 사용되는 loss
- image conditioned language modeling (LM) : image로부터 caption을 생성하기 위해 image-grounded text decoder에서 사용되는 loss
- Captioning and Filtering (CapFilt) : web에서 얻은 데이터를 활용하기 위해 noisy한 image-text 데이터셋을 bootstrapping하기 위한 방법입니다. pre-trained MED를 아래의 두개 module로 finetune해 얻습니다.
** bootstrap : Holdout/k-fold Cross Validation과 같은 Resampling 방식 중 하나로, 복원 추출법(중복으로 추출이 가능)을 활용해 집단 N개 중에 n개를 중복으로 뽑아, 모집단에 대한 분포를 표본 하나의 분포로 알아내는 방법
ex) 표본 {1,2,3} 하나에서 {3,1,3},{2,3,1},{2,2,1}와 같이 중복해서 복원추출
- 이미지를 통해 caption 텍스트를 합성하는 captioner. 즉, web 이미지 $I_w$에서 $T_s$를 만들어냅니다.
- image-text pair 중 text에서 noisy caption을 제거하는 filter. 즉, web 텍스트 $T_w$와 위의 $T_s$의 노이즈를 없앱니다.
다음으로 아래와 같은 여러가지 Task에 대해 Transfer Learning 을 진행가능합니다.
- Image-Text Retrieval : Image-To-Text Retrieval (TR)과 Text-to-Image retrieval(IR)로 나뉘며, 각각 이미지/텍스를 통해 관련있는 description을 찾아내는 방법입니다.
- Image Captioning
- Visual Question Answering (VQA) : 이미지에 대한 질문을 대답하는 기능입니다.
- Natural Language Visual Reasoning (NLVR) : 모델에게 한쌍의 이미지가 주어진 문장을 설명하고 있는지를 묻는 기능입니다.
- Visual Dialog (VisDial) : VQA에서 더 나아가 conversational 한 기능을 가지는 기능입니다.
3. LLAVA (LLaVA: Large Language and Vision Assistant)
[LLava1.0] LLAVA : Visual instruction tuning(NIPS’23)
[LLava1.5] Improved Baselines with Visual Instruction Tuning (arxiv'23)
LLM(Large-Language Model)에서 활용하는 Instruction tuning 기법을 차용해, LMM(Multi-modal Model)을 학습하는 방법입니다.
** Instruction Tuning : LLM을 사용자의 의도에 맞게 최적화하는 기법으로, 명확한 사용자 지시 사항을 제공하여 원하는 결과를 얻도록 하는 방법입니다.
** Finetuned Language Models are Zero-shot Learners (ICLR’22)
Chat-GPT와 GPT4과 같은 human instruction을 따르는 aligned LLM은 다양한 language로 표현된 instruction이 존재하는 모델을 관심있는 task로 변화하는 것이 가능하다는 것을 보였다고 합니다. 이의 결과로 LLAMA, Alpaca, Vicuna, GPT-4-LLM와 같은 open-source LLM들은 machine-generated instruction 샘플을 활용해 LLM의 alignment 능력을 향상할 수 있었습니다.
따라서 본 논문은 이와 비슷한 visual instruction tuning을 제안하여 instruction을 language-image인 multimodal space에서 주어 general-purpose의 visual assistant를 만들어냅니다.
방법으로는 아래와 같습니다.
- 먼저, LLM를 활용해 multi-modal language-image instruction을 따르는 데이터를 만듭니다. 즉, ChatGPT나 GPT-4와 같은 LLM을 활용해 image-text pair를 적절한 instruction을 따르는 포맷으로 바꾸어줍니다.
- 위 데이터를 활용해 아래와 같은 구조의 LMM으로 visual-instruction tuning을 진행합니다.
- Visual Encoder : CLIP
- Language Decoder : Vicuna, LLAMA
instruction을 따르는 데이터 생성하는 방법을 먼저 살펴보겠습니다. 아래와 같은 input을 활용합니다
- Context type1 : 이미지와 관련된 caption
- Context type2 : 이미지에 존재하는 caption과 연관된 bounding box들의 정보
이제 prompt를 만들어보겠습니다. 먼저 system의 content를 아래와 같이 명시해줍니다.
다음으로 user와 assistant의 content를 아래와 같이 명시해주는데, user의 content에 위의 두 input을 넣어줍니다.
그 다음, 이제 query['context']를 아래에 넣어줄 예정입니다. 이를 통해 query['response']를 얻어낼 예정입니다.
방식은 아래와 같이 conversation/detailed description/complex reasoning 세가지를 활용합니다.
이를 통해 158K의 데이터를 생성해냅니다.
다음으로 학습은 위에서 설명한 바와 같이 아래의 구조로 진행합니다. 이미 $X_v$에서 visual encoder를 활용해 $Z_v$를 만들고, projection matrix를 활용해 word embedding과 차원을 맞춘 $H_v$를 만들어냅니다.
$X_v$와 $X_q$의 instruction을 아래와 같이 t=1일 때만 visual input을 넣어주고, 이후에는 language token만을 넣어줍니다.
$$X^t_{instruct}=\left\{\begin{matrix}
[X^1_q,X_v]\ randomly,&t=1\\
X^t_q,&t>1
\end{matrix}\right.$$
이와 같은 과정으로 두개의 Stage를 통해 학습합니다.
- Stage1. Pre-training for Feature Alignment : visual encoder(frozen), LLM(frozen), linear layer(training)
- Stage2. Fine-tuning End-to-End : visual encoder(frozen), LLM(training), linear layer(training)
특히 Stage2에서는 Multimodal Chatbot과 Science QA에 대한 시나리오로 학습을 진행합니다.
------------------------------------------------------
b. Multi-layer Dataset : {text, foreground layer, background layer} pair
다음으로 여러개의 layer를 생성하기 위한 dataset을 준비하는 과정을 살펴보겠습니다.
- pretrained LLM을 통해 prompt pair를 얻습니다.
- pretrained LLM은 초기 100k는 ChatGPT를 활용했으며, 뒤 900k는 LLAMA2를 활용했다고 합니다.
** LLama 2: Open Foundation and Fine-Tuned Chat Models (arxiv'23) - prompt pair 예시
- foreground prompt : “a cute cat”,
- entire image prompt : “cat in garden”,
- background prompt : “nothing in garden”
- pretrained LLM은 초기 100k는 ChatGPT를 활용했으며, 뒤 900k는 LLAMA2를 활용했다고 합니다.
- 위에서 얻은 foreground prompt를 직접 학습했던 transparent 이미지 생성 모델에 넣어 결과를 얻습니다.
- 위 그림과 같이 RGB이미지와 alpha mask가 얻어집니다.
- 위에서 얻은 entire image prompt와 alpha mask와 함께 SDXL-inpaint에 넣어 background 부분을 생성해냅니다.
- alpha mask 중 alpha <1.0 인 곳에 대해 transparent로 정의합니다.
- 위에서 얻은 background prompt와 inverted mask와 함께 SDXL-inpaint 넣어 foreground 부분의 background를 생성해냅니다.
- inverted mask는 기존의 alpha mask를 invert(반전)한 후, erosion을 k=8로 진행합니다.
- 1M개의 dataset을 얻을 때까지 진행합니다.
** 위 내용 중 erosion에 대해 추가로 궁금하신 분들은 아래 더보기를 참조하세요
-------------------------------------------------------------------
<Morphology(모폴로지) 란?>
노이즈 제거, 구멍 채우기, 끊어진 선 이어 붙이기 등에 쓰이는 image processing 기법입니다.
1. Dilation (팽창)
큰 값을 더 크게, 작은 값을 더 작게 하여 픽셀값간의 차이를 극대화하는 연산입니다. 예를 들어 kernel의 크기 k=3인 경우, 중심 픽셀의 주변 3x3행렬 범위에서 가장 max인 값을 찾고, 이 값을 중심 픽셀에 적용하는 것입니다. 이때 kernel은 SE(Structuring Element)라고 부르기도 합니다.
$$\begin{matrix}
(I\oplus k)(y,x)=max_{(k_y,k_x)\subseteq k}(I(y-k_y,x-k_x)+k(k_y,k_x))\\
I:Image\sim y,x\\
k:kernel\sim k_y,k_x
\end{matrix}$$
주로 object를 확장해, 구멍을 채우거나 분리된 object를 연결하는데 사용합니다.
2. Erosion(침식)
큰 값을 작게 작은 값을 크게 하여 전체적으로 평평하게 만드는 연산입니다. 예를 들어 kernel의 크기 k=3인 경우, 중심 픽셀의 주변 3x3행렬 범위에서 가장 min인 값을 찾고, 이 값을 중심 픽셀에 적용하는 것입니다.
$$\begin{matrix}
(I\ominus k)(y,x)=min_{(k_y,k_x)\subseteq k}(I(y+k_y,x+k_x)-k(k_y,k_x))\\
I:Image\sim y,x\\
k:kernel\sim k_y,k_x
\end{matrix}$$
noise같은 작은객체를 제거하거나, 경계를 부드럽게 할때 사용합니다.
하지만 실제 응용에서는 Erosion/Dilation을 단독으로 하나만 쓰지는 않습니다.
3. Open
Erosion을 통해 외부의 작은 픽셀을 제거하고, Dilation을 통해 윤곽선을 단순화 시킵니다.
$$A\circ B=(A\ominus B)\oplus B$$
noise같은 작은객체를 제거하거나, 볼록한 부분을 완화함으로써 경계를 부드럽게 할때 사용합니다.
4. Close
Dilation을 통해 객체 내부 빈 공간을 메꾸고 윤곽선이 두터워지게 만든 후, Erosion을 통해 내부 공간을 단단하게 만듭니다.
$$A\bullet B=(A\oplus B)\ominus B$$
작은 구멍을 메우고, 오목한 부분을 채워넣음으로써 전체적인 윤곽을 파악하고 싶을 때 사용합니다.
-------------------------------------------------------------------
3. Results
본 논문에서 제안했던 데이터셋 준비와 학습 모델에 대해서 살펴봤는데, 이제 실험 결과에 대해 살펴보겠습니다.
a. Setting
먼저 실험하는데 사용한 셋팅에 대해 한번 살펴보겠습니다.
간단하게 학습에 활용한 하이퍼 파라미터 및 셋팅은 아래와 같습니다.
- Optimizer : AdamW
- Learning Rate :1e-5
- pretrained model : SDXL
- LoRA : 모든 layer에 대해 256 rank에서 활용
추가적으로, 전체 학습은 4개의 (A100 8G NV-link)를 활용해 data collection을 제외하고 1주정도 걸렸으며, 중간중간의 data colletion은 10k번의 iterations을 round당 16 batch로 작업했다고합니다.
b. Qualitative Results
정성적 결과에 대해 먼저 살펴보겠습니다.
1. Single-image, Base model
먼저 transparent한 하나의 이미지를 생성하는 base model의 결과를 보겠습니다.
아래 그림과 같이 text를 넣어주었을 때의 diverse한 컨텐츠의 이미지를 생성 가능한 것을 볼 수 있습니다.
2. Multi-layer model
다음으로 Multi-layer 모델의 결과를 살펴보겠습니다.
아래 그림을 보시면, text를 넣어 주었을 때, foreground이미지와 background이미지가 나온 것을 볼 수 있습니다.
foreground와 background 이미지가 coherent하게 학습되었기 때문에, foreground 오브젝트의 위치가 조화롭게 생성된 것을 볼 수 있습니다. 또한, 본논문에서는 결과적으로 illumination(조명), geometric(기하학적)인 부분 뿐아니라, 색채와 같은 미적인 부분도 잘 조화되어있다고 합니다.
3. Conditional layer generation
다음으로, 위에서 살펴보았던 아래와 같은 conditional한 학습이 잘되었는지에 대한 결과를 살펴보겠습니다.
- a. foreground를 활용해 background를 생성
- b. background를 활용해 foreground를 생성
아래는 "b. background를 활용해 foreground를 생성"의 결과입니다.
text와 background를 제공했는데, foreground의 위치가 잘 어울리게 생성된 것을 알 수 있습니다.
추가적으로 아래 사진과 같이 text와 background를 condition으로 생성된 foreground와 합쳐준 뒤 다시 이 이미지를 background 컨디션으로 제공하는 등, 반복적으로 진행하더라도 잘나오는 것을 확인할 수 있습니다.
또 다른 Conditional 모델이었던 아래의 모델에 대해서는 따로 결과가 나와있지 않습니다.
- c. foreground를 활용해 blended를 생성
- d. background를 활용해 blended를 생성
- e. (foreground, blended)를 활용해 foreground를 제거
- f. (background, blended)를 활용해 background를 제거
c. Ablation Study
다음으로 Ablation Study에 대해 살펴보겠습니다.
Ablation Study는 Latent transparency를 다른 방법으로 시도한 것과 비교하는 방식으로 진행했습니다.
먼저 기존의 Stable Diffusion의 차원과, alpha channel을 강제로 3번 copy한 후 UNet에서 8개의 채널을 처리하도록한 방법과 비교했습니다. 이 때, 기존 VAE encoder와 비교한 차원은 아래와 같습니다.
- VAE encoder : 512x512x3 → 64x64x4
- VAE encoder (add VAE encoder) : 512x512x3, 512x512x3 → 64x64x(4+4)
이와 같이 진행하면 VAE는 frozen되어 있으므로, UNet에서 처리할 latent distribution이 변해 당연하게 결과가 아래 그림 (a)와 같이 잘 나오지 않는다고 합니다.
** 이는 Control을 위해 UNet의 input으로 넣어주는 것과는 다릅니다. 예를 들어, Control로 넣어주는 경우는 UNet의 결과가 control채널을 제외한 이미지의 noise만 얻게 되지만, 이 경우는 해당 채널이 iterative하게 반복적으로 다음 인풋으로 활용됩니다.
다음으로 VAE Encoder에 alpha채널을 하나 추가하는 방법과 비교했습니다. 기존 VAE encoder와 비교한 차원은 아래와 같습니다.
- VAE encoder : 512x512x3 → 64x64x4
- VAE encoder(add alpha 1 channel) : 512x512x(3+1) → 64x64x4
이 경우에도 아래 그림 (b)와 같이, 학습이 굉장히 불안정한 것을 볼 수 있습니다. 이 또한 latent distribution이 변했다고 볼 수 있습니다.
d. vs Ad-hoc method
다음으로 Ad-hoc한 방법과 비교하기 위해 사람 14명이 직접 평가하는 방식으로 user study를 진행했습니다.
(11 온라인 작업자, 1명의 학생, 2명의 전문 크리에이터)
먼저 기존의 Ad-hoc한 SOTA Matting 기법들을 소개하겠습니다.
- PPMatting [9] : Pp-matting: High-accuracy natural image matting (arxiv'22)
SOTA matting 모델로, tri-map 없이 automatic하게 동작합니다. - Matting Anything [26] : Matting anything (arxiv'23)
Segment Anything Model (SAM)을 base model로 활용해 matting을 진행하도록 fine-tune한 모델로, 역시나 tri-map없이 동작합니다. - VitMatte [57] : Vitmatte: Boosting image matting with pre-trained plain vision transformers (IF'24)
위와 다르게 tri-map을 활용하며, Vision Transformer(ViT)를 base모델로 활용합니다.
이 논문과, 위에서 소개한 [9]와 [26] 모델 3개의 방법에 대해 각각 100가지의 결과를 뽑아 비교했으며, 100가지 중 선호도 %는 아래 표의 Group 1과 같습니다.
또한 추가적으로 commercial asset을 Adobe Stock에서 구해 이 논몬의 결과와 선호도를 조사를 진행하니, 선호도가 본 논문의 모델과 아래 Group2와 같이 비슷하게 나왔다고 합니다.
4. How to use
그럼 이번엔 본논문인 Layerdiffuse를 활용하는 방법에 대해 소개하겠습니다.
Layerdiffuse는 다양한 Stable Diffusion용 Web UI에서 공개되었는데, Github(https://github.com/layerdiffusion/LayerDiffuse)에 현재 공개된 방법은 아래와 같은 두가지 방법이 있습니다.(2024년 5월 10일 기준)
- ComfyUI
- Stable Diffusion Web UI - Forge
위 두가지 방법을 순서대로 보이겠습니다.
----------------------------------------------------------
<다양한 SD용 Web UI 비교>
SD를 실행하기 위한 Web UI는 처음에 A1111이 등장했지만 현재는 다양한 Web UI가 존재하며 각각 다른 특징을 가지고 있습니다. 이들에 대해 간단히 얻은 정보만 정리해보겠습니다.
1. A1111(https://github.com/AUTOMATIC1111/stable-diffusion-webui)
가장 오래되어 기능이 많으며, ControlNet기반의 extension이 특히나 많다고 합니다.
2. ComfyUI(https://github.com/comfyanonymous/ComfyUI)
아래에서 다시 소개하겠지만 workflow 기반의 Web UI이며, custom workflow를 만들수 있는 flexibility가 있어 control이 많이 필요한 경우 사용하기 유리합니다.
3. Fooocus(https://github.com/lllyasviel/Fooocus
Comfy backend를 가졌으며, ImagePrompt와 같이 inpainting을 위해 독특하고 유용한 툴이 있습니다. 또한 Mac을 지원해서 사용하는 분들도 있다고 합니다.
4. Forge (https://github.com/layerdiffusion/sd-forge-layerdiffuse.git)
아래에서 다시 소개하겠지만 위 A1111의 개선된 fork로 다른 Backend를 통해 조금 더 개선된 성능을 가집니다. 또한 Extension을 만들기에 편리한 특징을 가지고 있습니다.
** 특히 최신 GPU가 아닌 옛날 GPU에서 성능이 유리하다고 합니다.
하지만 Extension을 위한 flexibility가 부족한 단점도 있다고 합니다.
5. SD.Next(https://github.com/vladmandic/automatic)
역시나 A1111의 fork이며, resource관리에 유리하다고 합니다.
----------------------------------------------------------
a. ComfyUI
ComfyUI는 Stable Diffusion을 활용하기 위한 Web UI 중 하나로, SD뿐 아니라 다양한 Custom Node들을 연결해 Workflow를 구성하고 편집하는 방식을 가집니다. 최신 트렌드를 직관적인 UI로 활용하기 좋은 편의성 덕에 많이 쓰이기 시작했습니다.
ComfyUI는 간단하게만 소개할 계획이며, 활용하기 위한 다양한 가이드가 존재하니 참조하시길 바랍니다.
** https://blenderneko.github.io/ComfyUI-docs/
** https://openart.ai/workflows/academy
1. 설치 & 실행
먼저 공식 Github(https://github.com/comfyanonymous/ComfyUI)을 활용해 아래와 같이 설치를 진행합니다.
git clone https://github.com/comfyanonymous/ComfyUI.git
pip3 install -r requirements.txt
실행은 아래와 같은 명령어로 진행합니다. 외부에서 접속하기 위해 IP와 포트를 지정해줍니다.
python3 main.py --listen=0.0.0.0 --port 45555
2. 활용
실행한 서버의 IP가 11.12.13.14 라고 할때 http://11.12.13.14:45555 로 접속하면 실행화면은 아래와 같습니다.
위 그림에 표시된 각각 기능에 대해 간단히 소개하겠습니다.
- save/load/refresh/clear 버튼 : 왼쪽에 보이는 그래프 형태를 가지는 노드들의 구조를 workflow라고 부르는데, 이 workflow를 workflow.json로 저장하고 불러오고 Refresh하고 Clear하는 기능을 의미합니다.
** 다양한 workflow를 커뮤니티(https://comfyworkflows.com/)에서 받을 수 있습니다. - Node 추가하기 : 새로운 노드를 추가하기 위해 더블클릭 후 검색하거나 오른쪽 클릭후 "add_nodes"를 클릭합니다.
- Queue Prompt : 현재의 workflow를 실행하는 방법입니다.
위와 같은 workflow를 실행하는데 있어서, 서버의 폴더트리 중 몇가지를 알아두어야 할 필요가 있습니다.
- comfyUI/models/*
- checkpoints/* : SD, SD-XL 등 전체 모델의 체크포인트를 넣어두는 곳 (주로 safetensors 형태)
- controlnet/* : ControlNet, T2IAdapter등의 체크포인트를 넣어놓는 곳 (주로 safetensors 형태)
- loras/* : LoRA 등의 체크포인트를 넣어놓는 곳 (주로 safetensors 형태)
- comfyUI/custom_nodes/* : 새로운 Custom node를 설치하기 위해 사용하는 폴더입니다. 자세한 내용은 아래에 소개됩니다.
- comfyUI/output/* : Queue Prompt 실행시 output이 default로 저장되는 위치입니다.
- comfyUI/input/* : input이 default로 저장되는 위치입니다.
3. Custom Node 설치
ComfyUI에서 활용하는 노드 중, 외부에서 만든 Custom Node들을 직접 설치하는 경우가 많습니다.
이런 Custom Node들을 설치하기 위해서는 먼저 ComfyUI-Manager라는 것을 설치하는 것이 편한데, 이 ComfyUI-Manager마저도 Custom Node입니다.
따라서 이 CumfyUI-Manager를 설치하는 방법과 함께, Custom Node를 설치하는 방법을 소개하겠습니다.
- 방법1. 직접 폴더에 설치
위에서 언급했던 comfyUI/custom_nodes 디렉토리 안으로 이동한뒤 아래와 같은 명령어를 통해 해당 git을 위치시켜줍니다.
git clone https://github.com/ltdrdata/ComfyUI-Manager.git
그다음 ComfyUI가 켜져 있는 경우 재실행해줍니다.
이와 같은 방법으로 ComfyUI-layerdiffuse(https://github.com/huchenlei/ComfyUI-layerdiffuse.git)를 설치 할 수도 있습니다.
- 방법2. ComfyUI-Manager 활용하기
ComfyUI-Manager가 설치되어 있는 경우 첫화면에 Manager 탭이 생기게 됩니다. 해당 탭을 누르면 아래와 같이 뜹니다.
위에서 Install Custom Nodes 버튼 혹은 Install Models 버튼을 통해 External Custom node들을 설치해줄 수 있습니다.
우리는 Custom Node를 설치하는 방법을 살펴보고 있으므로, Install Custom Nodes를 클릭해보겠습니다.
위 그림과 같이 설치하고 싶은 Custom Node를 검색해 설치할 수 있습니다. 역시나 설치한 후에는 ComfyUI를 재실행해주어야합니다.
위는 우리가 설치할 ComfyUI-layerdiffuse를 설치한 화면입니다.
4. Layerdiffuse 활용
그럼 layerdiffuse를 활용해보겠습니다. 먼저 해당 Github에서 제공하는 default workflow를 실행한 화면을 살펴보겠습니다.
위 빨간색으로 표시한 노드를 조금 자세히 살펴보겠습니다.
먼저 Layer Diffuse Apply는 위에서 설명했던 투명한 foreground 이미지를 생성하는 base model 입니다. 또한 Layer Diffuse Decode는 위에서 설명한 latent transparency decoder $\mathcal{D}$로, VAE Decode의 결과(images)와 latent(samples)를 활용해 {RGB,alpha}를 각각 만들어냅니다.
** 다른 노드들에 대해 궁금하시면 아래 더보기를 참조하세요
--------------------------------------------------------------
<ComfyUI Layerdiffuse에서 활용할 수 있는 노드들>
Layerdiffuse에는 위에서 보인 노드 외에 아래와 같은 다양한 노드들이 존재합니다.
다양한 Node들에 대한 설명을 간단히 적어보겠습니다.
(복습) 위에서 condition을 주기 위해 다양한 버전이 있었다는 것을 참조하시길 바랍니다.
- a. foreground를 활용해 background를 생성
- b. background를 활용해 foreground를 생성
- c. foreground를 활용해 blended를 생성
- d. background를 활용해 blended를 생성
- e. (foreground, blended)를 활용해 foreground를 제거
- f. (background, blended)를 활용해 background를 제거
먼저 DM 모델에 Layerdiffuse를 적용하기위한 Apply 노드들은 아래와 같습니다.
- LayeredDiffusionApply (LayeredDiffusionFG) : Transparent한 foreground 이미지를 생성하는 base model 입니다. (Attention Sharing 사용)
- LayeredDiffusionJointApply (LayeredDiffusionJoint) : {FG,BG,Blended}를 한번에 생성하는 multi-layer model로 batch size를 3N개로 주어야합니다. (Attention Sharing 사용)
- LayeredDiffusionCondApply (LayeredDiffusionCond) : 위 c,d와 같이 blended 이미지를 생성합니다.
- FG => Blended
- BG => Blended
- LayeredDiffusionCondJointApply (LayeredDiffusionCondJoint) : (조금 특이한 버전이지만) background 이미지를 활용해 {foreground, blended}를 생성하는 방법입니다. (Attention Sharing 사용)
- FG => Blended + BG
- BG => Blended + FG
- LayeredDiffusionDiffApply (LayeredDiffusionDiff) : 위 e,f와 같이 blended이미지에서 삭제합니다.
- Blended + FG => BG
- Blended + BG => FG
다음으로 생성된 latent들을 통한 latent transparency decoder $\mathcal{D}$ 노드들입니다.
- LayeredDiffusionDecode (LayeredDiffusionDecode) : latent를 활용해 {RGB,alpha}를 각각 만들어냅니다.
- [B, C=3, H, W] => [B, C=4, H, W]
- LayeredDiffusionDecodeRGBA (LayeredDiffusionDecodeRGBA) : latent를 활용해 RGBA를 만들어냅니다.
- [B, C=3, H, W] => [B, C=4, H, W]
- LayeredDiffusionDecodeSplit (LayeredDiffusionDecodeSplit) : 생성된 RGBA들을 여러개의 이미지로 나누어 보여줍니다.
--------------------------------------------------------------
b. SD Web UI
Stable Diffusion Web UI는 웹 기반의 UI를 통해 Stable Diffusion의 다양한 기능을 사용할 수 있도록 만들어 놓은 프로젝트 입니다.
Forge(https://github.com/layerdiffusion/sd-forge-layerdiffuse.git)는 기존 버전인 A1111의 개선된 fork로 다른 Backend를 통해 조금 더 개선된 성능을 가집니다. 또한 Extension을 만들기에 편리한 특징을 가지고 있습니다. 하지만 Extension을 위한 flexibility가 부족한 단점도 있다고 합니다.
1. 설치 및 실행
LayerDiffuse는 Forge의 Extension이므로, SD Web UI Forge를 설치해주어야 하므로, 이를 설치하는 과정을 보일 계획입니다. 하지만 SD Web UI를 설치하는 방법 또한 똑같습니다.
먼저 필요한 패키지들을 설치해줍니다.
apt-get install python3-venv
pip3 install xformers
다음 해당 git을 불러와 아래와 같이 설치해줍니다. 이때, webui.sh파일을 통해 설치를 진행하는데, 필자는 Docker내부에서 실행하기 때문에 편의상 해당 파일의 내용을 아래와 같이 바꾸어주었습니다. 이는 선택적으로 하셔도 됩니다.
- use_venv=0
- can_run_as_root=1
git clone https://github.com/lllyasviel/stable-diffusion-webui-forge
./webui.sh —xformers
다음으로 이제 실행을 해보겠습니다. 외부에서 실행하기 위해 pyproject.toml의 내용을 아래와 같이 바꾸었습니다.
- base_url =“http://0.0.0.0:7860”
다음, 아래의 명령어를 통해 실행해주었습니다.
./webui.sh --listen --share --port 45555 --enable-insecure-extension-access --no-gradio-queue --xformers --no-half-vae --api
2. 활용
실행한 서버의 IP가 11.12.13.14 라고 할때 http://11.12.13.14:45555 로 접속하면 UI를 활용할 수 있습니다.
SD Web UI의 경우 사용에 어려움이 없기 때문에, 실행화면은 아래 Extension을 함께 실행할 때 보이겠습니다.
해당 UI를 활용하는데 있어서, 서버의 폴더트리 중 몇가지를 알아두어야 할 필요가 있습니다.
- stable-diffusion-webui/models/* :
- Stable-diffusion/* : SD, SD-XL 등 전체 모델의 체크포인트를 넣어두는 곳 (주로 safetensors 형태)???
- ControlNet/* : ControlNet, T2IAdapter등의 체크포인트를 넣어놓는 곳 (주로 safetensors 형태)
- Lora/* : LoRA 등의 체크포인트를 넣어놓는 곳 (주로 safetensors 형태)
- layer_model/* : 뒤에서 사용할 layerdiffuse모델의 체크포인트들이 들어갈 곳
- stable-diffusion-webui/extension/* : 새로운 extension을 설치하기 위해 사용하는 폴더입니다. 자세한 내용은 아래에 소개됩니다.
- stable-diffusion-webui/output/* : 실행시 output이 default로 저장되는 위치입니다.
- stable-diffusion-webui/pyproject.toml : 실행 할 때의 서버의 옵션들을 수정하기 위한 파일입니다.
3. Extension 설치
- 방법1. 직접 폴더에 설치
stable-diffusion-webui/extension 폴더 내부에 직접 git clone을 통해 설치해줍니다.
- 방법2. SD Web UI를 활용하기
직접 UI를 활용해 설치할 수 있습니다.
먼저 아래 그림과 같이, Extensions > Install from URL 탭으로 들어가 내용을 적어 줍니다.
- URL for extension's git repository : https://github.com/huchenlei/ComfyUI-layerdiffuse.git
- Specific branch name : main
이후에 Extensions > Installed 탭에 들어가 "Apply and restart UI"를 눌러 재시작 해줍니다.
4. Layerdiffuse 활용
위와 같이 Extension을 설치하고 나면 아래 그림과 같이 Layerdiffuse Extension이 설치된 것을 확인할 수 있습니다.
해당 탭을 자세히 열어 보면 아래와 같습니다. 먼저 Enabled를 통해 생성할 때 이를 활용하도록 해준 뒤에, 방법을 선택해 줍니다. 아래는 (SDXL) Only Generate Transparent Image (Attention Injection)을 선택해주었습니다.
---------------------------------------------------------
<Forge Layerdiffuse에서 활용할 수 있는 옵션들>
Layerdiffuse에는 위에서 보인 노드 외에 아래와 같은 다양한 옵션들이 존재합니다.
다양한 옵션들에 대한 설명을 간단히 적어보겠습니다.
(복습) 위에서 condition을 주기 위해 다양한 버전이 있었다는 것을 참조하시길 바랍니다.
- a. foreground를 활용해 background를 생성
- b. background를 활용해 foreground를 생성
- c. foreground를 활용해 blended를 생성
- d. background를 활용해 blended를 생성
- e. (foreground, blended)를 활용해 foreground를 제거
- f. (background, blended)를 활용해 background를 제거
먼저 Transparent한 foreground 이미지를 생성하는 base model 입니다.
- "(SD1.5) Only Generate Transparent Image (Attention Injection)” (FG_ONLY_ATTN_SD15) (Attention Sharing 사용 가능)
- "(SDXL) Only Generate Transparent Image (Attention Injection)” (FG_ONLY_ATTN)
- "(SDXL) Only Generate Transparent Image (Conv Injection)” (FG_ONLY_CONV)
다음으로, {FG,BG,Blended}를 한번에 생성하는 multi-layer model입니다.
- "(SD1.5) Generate Everything Together (need batch size 3)” (JOINT_SD15) (Attention Sharing 사용 가능)
다음으로, 위 a,b와 같이 conditional하게 생성합니다.
- "(SD1.5) From Foreground to Background (need batch size 2)” (FG_TO_BG_SD15) (Attention Sharing 사용 가능)
- "(SD1.5) From Background to Foreground (need batch size 2)” (BG_TO_FG_SD15) (Attention Sharing 사용 가능)
다음으로 위 c,d와 같이 blended 이미지를 생성합니다.
- "(SDXL) From Foreground to Blending” (FG_TO_BLEND)
- "(SDXL) From Background to Blending” (BG_TO_BLEND)
다음으로 위 e,f와 같이 blended이미지에서 삭제하는 모델입니다.
- "(SDXL) From Foreground and Blending to Background” (FG_BLEND_TO_BG)
- "(SDXL) From Background and Blending to Foreground” (BG_BLEND_TO_FG)
---------------------------------------------------------
자 이제 생성을 진행해 보겠습니다. 아래와 같이 Positive Prompt와 Negative Prompt를 적어준 뒤, Generate를 실행하면 아래와 같이 Transparent 이미지와 RGB채널 이미지 두가지가 나오는 것을 확인할 수 있습니다.
- Positive Prompt : banana, empty background, best quality, masterpiece
- Negative Prompt : low quality
한가지 버전을 더 소개하기 위해 {FG,BG,Blended}를 한번에 생성하는 multi-layer model인 (SD1.5) Generate Everything Together을 선택해보겠습니다. 아래와 같이 prompt를 주었습니다.
- Positive Prompt : banana, best quality, masterpiece
- Negative Prompt : low quality
- Background Additional Prompt : forest
주의할 점은 아래 그림과 같이 Batch size를 3으로 바꿔주어야합니다.