그림으로 이해하는 Stable Diffusion (번역)
AI/NovelAI/Stable Diffusion/번역/
목차
AI에 의한 이미지 생성은 (나를 포함하여) 사람들을 놀라게 한 최신 AI 기능입니다. 텍스트 설명에서 인상적인 비주얼을 만드는 능력은 마치 마법과도 같으며, 인간이 예술을 창조하는 방식이 어떻게 변화할지 그 방향을 명확하게 가리킵니다. Stable Diffusion의 공개는 고성능(화질뿐만 아니라 속도와 비교적 낮은 리소스 / 메모리 요구 사항이라는 의미에서의 성능) 모델을 일반인에게 제공한다는 점에서, 개발 관점에서 명확한 마일스톤이라고 할 수 있겠습니다.
AI 이미지 생성을 시도해 보면 그 구조가 신경이 쓰이기 시작한 분도 많지 않을까요?
이 글에서는 Stable Diffusion의 구조에 대해 친절하게 소개해 보겠습니다.
Stable Diffusion은 다양한 방식으로 사용할 수 있어 범용성이 높습니다. 우선 텍스트만을 이용한 이미지 생성(text2img) 기능에 집중해 봅시다. 위의 이미지는 텍스트 입력과 생성된 이미지의 예시입니다. 텍스트를 이미지로 변환하는 것 외에도 또 다른 주요 사용법은 이미지를 재가공하는 것입니다 (즉, 입력값을 텍스트 + 이미지 로 했을 경우입니다).
이미지 생성의 옵션과 매개변수의 의미를 설명하는데 도움이 되는 구성 요소, 그들이 어떻게 상호 작용하는지, 내부를 살펴 보겠습니다.
Stable Diffusion은 여러 구성 요소와 모델로 구성된 시스템입니다. 일체화된 모놀리식 모델이 아닙니다.
내부를 들여다 보면, 먼저 관찰할 수 있는 것은 텍스트 정보를 텍스트 내의 아이디어를 포착해 숫자 표현으로 변환하는 텍스트 이해 컴포넌트가 있는 것을 알 수 있습니다.
여기에서는 대략적인 도면으로 시작하여 이 기사의 뒷부분에서는 기계 학습의 세부적인 내용을 설명합니다. 그러나, 이 텍스트 인코더는 특수한 트랜스포머 언어 모델(기술적으로는, CLIP 모델의 텍스트 인코더 라고 합니다)이라고 말할 수 있습니다. 입력된 텍스트를 받아서 텍스트의 각 단어/토큰을 나타내는 숫자 목록(벡터)을 출력합니다.
그런 다음 정보는 이미지 생성기(image generator)에 전달됩니다. 이미지 생성기는 여러 컴포넌트로 구성됩니다.
이미지 생성기는 두 단계를 거쳐 수행됩니다.
이 컴포넌트가 Stable Diffusion의 핵심 비법 소스입니다. 이전 모델에 비해 성능적으로 많은 향상이 있었던 것은 여기에서 비롯된 것입니다.
이 컴포넌트는 이미지 정보를 생성하기 위해 여러 단계로 실행됩니다. 이것은 Stable Diffusion의 인터페이스와 라이브러리의 스텝 파라미터로, 보통 50과 100를 기본값으로 설정됩니다.
이미지 정보 생성기는 전적으로 이미지 정보 공간(image information space) 또는 잠재 공간(latent space)에서 동작합니다. 이것이 무엇을 의미하는지에 대해서는 후반부에서 자세히 설명합니다. 이 특성은 픽셀 공간에서 작동했던 이전의 확산 모델보다 빠르게 작동합니다. 기술적으로 말하면, 이 컴포넌트는 UNet 신경망(neural network)과 스케줄링 알고리즘으로 구성됩니다.
"확산(diffusion)"이라는 단어는 이 컴포넌트에서 일어나는 일을 나타냅니다. 최종적으로 (다음 컴포넌트인 이미지 디코더에 의해) 고품질의 이미지가 생성되는 것은, 정보를 단계적으로 처리하기 때문입니다.
이미지 디코더는 정보 생성기로부터 얻은 정보를 바탕으로 그림을 그립니다. 프로세스의 끝에 한 번만 실행되어 최종 픽셀 이미지가 생성됩니다.
이를 통해 Stable Diffusion을 구성하는 3가지 주요 컴포넌트(각각 자체적인 신경망을 가짐)가 보일 것입니다.
ClipText : 텍스트 인코딩 용도
UNet + Scheduler : 정보(잠재) 공간 내에서 정보를 점진적으로 처리/확산
오토인코더 디코더(Autoencoder Decoder) : 처리를 거친 정보 배열을 사용해서, 최종적인 이미지 결과물을 출력
확산은 도면에서 핑크색 "이미지 정보 생성기" 컴포넌트 내부에서 수행되는 처리(process)를 말합니다. 입력 텍스트를 나타내는 토큰 임베딩(token embedding), 랜덤한 시작 이미지 정보 배열(image information array, 이것을 '잠재(latents)'라고 함)을 사용하여, 처리에서는 이미지 디코더가 최종 이미지를 그리는데 사용하는 정보 배열을 생성합니다.
이 처리는 단계적으로 수행됩니다. 각 단계마다 더 관련성이 높은 정보가 추가됩니다. 이 처리를 직관적으로 이해하기 위해 랜덤한 잠재 배열을 검사하여 시각적 노이즈로 변환되는지 확인할 수 있습니다. 이 경우의 "시각적 검사(Visual inspection)"란, 즉 배열을 이미지 디코더에 통과시키는 것입니다.
확산은 여러 단계로 수행되며, 각 단계는 입력된 잠재 배열로 조작하고, 모델이 학습했던 모든 이미지 중에서, 입력된 텍스트 및 모든 시각적 정보와 많이 가깝다고 모델이 선택한, 또다른 잠재 배열을 생성합니다.
이러한 잠재(latent)들의 모음을 시각화하면, 각 단계에서 어떤 정보가 추가되는지 확인할 수 있습니다.
이 과정은 보면 정말 숨이 막힐 정도입니다.
이 경우 2단계와 4단계 사이에 특히 흥미로운 일이 발생합니다. 마치 노이즈 속에서 윤곽이 떠오르는 것 같습니다.
확산 모델을 이용한 이미지 생성의 중심이 되는 아이디어는, 우리가 강력한 컴퓨터 비전 모델(vision model)을 가지고 있다는 사실에 달려 있습니다. 충분한 양의 데이터 세트가 있으면 이러한 모델은 복잡한 작업을 학습할 수 있습니다. 확산 모델은 다음과 같은 문제를 조립하여 이미지 생성에 접근합니다.
예를 들어, 어떤 이미지가 있다면 첫 번째 단계로 이미지에 노이즈를 추가해 봅시다.
이 이미지에 추가한 노이즈의 '슬라이스(slice)'를 '노이즈 슬라이스 1(noise slice 1)'이라고 해봅시다. 이제 노이즈가 있는 이미지에 또다른 노이즈를 추가해 봅시다("노이즈 슬라이스 2").
이 시점에서 이미지는 온통 노이즈 투성이입니다. 그럼, 이것을 예시로 해서 컴퓨터 비전 신경망 학습을 살펴봅시다. 단계 번호와 이미지가 주어지면 이전 단계에서 얼마나 노이즈가 가해졌는지 예측합니다.
이 예시에서는 이미지에서 전체 노이즈까지 총 2단계입니다만, 이미지에 가하는 노이즈의 양을 우리가 제어할 수 있기 때문에 수십 단계로 나누어 학습 데이터 세트의 모든 이미지에 대해 이미지마다 수십 개의 학습 예제를 만들 수 있습니다.
놀라운 점은 이 노이즈 예측 네트워크가 제대로 작동하게 되면 여러 단계에 걸쳐 노이즈를 제거함으로써 효과적으로 이미지를 그릴 수 있다는 것입니다.
주: 이것은, 확산 알고리즘을 조금 단순화한 설명입니다. 아래의 자료는 수학적 전체 이미지를 보다 상세히 설명합니다.
학습된 노이즈 예측기는, 노이즈가 있는 이미지와 노이즈 제거 단계 수를 받아 노이즈 슬라이스를 예측할 수 있습니다.
노이즈 슬라이스를 예측할 수 있기 때문에, 이미지에서 이를 제거하면 모델이 학습한 이미지에 가까운 이미지를 얻을 수 있습니다.
만약 학습 데이터 세트가 미적으로 아름다운 이미지(예: Stable Diffusion이 학습한 LAION Aesthetics 등)라면, 결과적으로 출력되는 이미지 또한 미적으로 아름다운 것이 출력된다는 것입니다.
이상으로, 확산 모델에 의한 이미지 생성의 설명을 끝냅니다. 주로 "노이즈 제거 확산 확률 모델(Denoising Diffusion Probabilistic Models)"에서 설명한 대로입니다. 이제 이런 식으로 확산에 대해 직관적으로 이해했으니, Stable Diffusion 뿐만 아니라 Dall-E 2와 Google의 Imagen의 주요 구성 요소가 어떻게 작동하는지도 이해할 수 있습니다.
덧붙여 지금까지 설명한 확산 처리는, 텍스트 데이터를 사용하지 않고 이미지를 생성한 것이라는 점에 주의해 주세요. 다음 섹션에서는 텍스트가 확산 처리에 통합되는 방법을 설명합니다.
Stable Diffusion의 논문에서는, 이미지 생성 처리의 고속화를 위해서, 픽셀 이미지 그 자체가 아니고, 이미지를 압축한 것으로 확산 처리를 실행합니다. 논문에서는 이것을 "잠재 공간으로의 여행(Departure to Latent Space)"이라고 부릅니다.
이 압축(과 이후 과정인 압축 해제 / 그리기)는 오토인코더(autoencoder)를 통해 이루어집니다. 오토인코더는 인코더를 사용하여 이미지를 잠재 공간으로 압축하고 디코더를 사용하여 압축된 정보만을 사용하여 이미지를 재구성합니다.
이제 압축된 잠재 데이터에 대해 순방향 확산(forward diffusion) 처리가 실행됩니다. 노이즈 슬라이스는 픽셀 이미지가 아니라 이 잠재 요소에 적용된 노이즈 슬라이스입니다. 그리고, 노이즈 예측기는 실제로는 압축된 표현(잠재 공간)의 노이즈를 예측하도록 학습되는 것입니다.
(오토인코더의 인코더를 사용한) 순방향 프로세스(forward diffusion)는 노이즈 예측기를 학습시키기 위한 데이터를 생성하는 방법입니다. 학습이 완료되면 (오토인코더의 디코더를 사용하여) 역방향 프로세스(reverse process)를 수행하여 이미지를 생성할 수 있습니다.
이 두 가지 흐름은 LDM / Stable Diffusion 논문의 그림 3에 나와 있습니다.
이 그림은 "조건부(conditioning)" 컴포넌트를 추가적으로 보여줍니다. 이 경우엔, 모델이 생성해야하는 이미지를 설명하는 텍스트 프롬프트를 말합니다. 이제 텍스트 컴포넌트에 대해 알아봅시다.
텍스트 프롬프트를 입력받고, 토큰 임베딩(Token embeddings)을 생성하는 언어 이해 컴포넌트로서 Transformer 언어 모델이 사용됩니다. 공개된 Stable Diffusion 모델은 ClipText (GPT 기반 모델)를 사용하지만 논문에서는 BERT를 사용합니다.
언어 모델의 선택이 중요하다는 것이 Imagen의 논문에 제시되어 있습니다. 규모가 더 큰 이미지 생성 컴포넌트로 변경하는 것보다, 규모가 더 큰 언어 모델로 교체하는 것이 생성된 이미지의 품질에 더 큰 영향을 미쳤습니다.
언어 모델의 대규모화 및 개선은 이미지 생성 모델의 품질에 큰 영향을 미칩니다. 출처 : Saharia 등의 Google Imagen 논문 그림 A.5
초기 Stable Diffusion 모델은 OpenAI에서 출시한 학습된 ClipText 모델을 플러그인한 것입니다. 향후 모델은 새로 출시된 훨씬 더 큰 OpenCLIP 변종인 CLIP으로 전환될 수 있습니다. 이 새로운 배치(Batch)에는, ClipText의 63M 매개변수보다 더 큰, 최대 354M의 매개변수 크기의 텍스트 모델이 포함됩니다.
CLIP은 이미지와 캡션으로 구성된 데이터 세트로 학습합니다. 4억 개의 이미지와 캡션을 포함한, 다음과 같은 데이터 세트가 그 예시입니다.
CLIP은 이미지 인코더와 텍스트 인코더의 조합입니다. 그 학습 과정은 이미지와 그 캡션을 대입하는 과정이라고 간략화해서 생각할 수 있습니다. 우리는 이것들을 이미지 인코더와 텍스트 인코더로 각각 인코딩합니다.
그런 다음 결과물로 나온 임베딩을 코사인 유사도를 사용하여 서로 비교합니다. 학습 과정이 시작되면 텍스트가 이미지를 올바르게 설명하더라도 코사인 유사도는 낮게 나올 것입니다.
다음에 임베딩할 때는 결과값이 유사하도록, 두 모델을 업데이트합니다.
데이터 세트 전체와 대규모 배치 크기로 이것을 반복함으로써, 최종적으로 인코더는 개의 이미지와 "a picture of a dog"이라고 하는 문장이 비슷한 임베딩을 생성할 수 있게 되는 것입니다. word2vec 과 마찬가지로, 학습 과정에서 일치하지 않는 이미지나 캡션의 부정적인 예시도 포함해야 하며, 모델은 이들 예시에 낮은 유사도 점수를 할당해야 합니다.
텍스트를 이미지 생성 프로세스의 일부로 만들기 위해, 텍스트를 입력값으로 사용하도록 노이즈 예측기를 조정해야 합니다.
데이터 세트는 이제 인코딩된 텍스트를 포함합니다. 잠재 공간에서 작동하기 때문에 입력 이미지와 예측된 노이즈가 모두 잠재 공간에 있습니다.
텍스트 토큰이 Unet에서 어떻게 사용되는지 더 잘 이해하기 위해, Unet 내부를 자세히 살펴 보겠습니다.
먼저 텍스트를 사용하지 않는 확산 Unet을 살펴 보겠습니다. 그 입력과 출력은 다음과 같습니다.
내부를 보면 이렇습니다.
이제 이 시스템을 어떻게 변경해서 텍스트에 대한 주의를 포함시켰는지 살펴보겠습니다.
텍스트 입력 지원 (기술 용어 : 텍스트 조건부(text conditioning))을 추가하는데 요구된 시스템 상의 주요 변경 사항은, ResNet 블록 사이에 주의(Attention) 레이어를 추가하는 것입니다.
resnet 블록이 텍스트를 직접 보고 있는 것이 아니라는 점에 주목해 주십시오. 그러나 주의 레이어는 잠재(latents) 속의 텍스트 표현들을 병합합니다. 이제 그 다음 ResNet은 이렇게 병합된 텍스트 정보를 처리 과정에서 사용할 수 있습니다.
Stable Diffusion의 구조에 대해, 이 글이 입문에 좋은 직관을 제공해줬기를 바라봅니다. 그 밖에도 많은 개념이 관련되어 있습니다만, 위에서 서술한 컴포넌트에 익숙해지면 이해하기 쉬워질 것이라 생각합니다. 아래의 참고자료들은 내가 도움이 될 것이라고 생각하는 양질의 심화자료입니다. 수정할 부분이나 피드백 사항이 있다면 Twitter 로 저에게 연락하십시오.