AI 이미지/Stable Diffusion

스테이블 디퓨전 - 부정적 프롬프트

하늘이푸른오늘 2024. 2. 1. 00:26

스테이블 디퓨전을 사용해 인공지능 이미지를 생성할 때, 부정적 프롬프트를 사용하면 원하는 이미지를 얻을 확률을 높여줍니다. 사실은 부정적 프롬프트만으로도 이미지를 생성할 수 있습니다. 

참고: 이 글은 부정적 프롬프트의 두가지 종류 중 하나입니다. 다른 하나는 부정적 이미지 프롬프트를 읽어보시기 바랍니다.

간단한 예

긍정적 프롬프트만 사용할 경우

남자 이미지를 몇장 생성해 보겠습니다. 여기에서는 Stable Diffusion v1.5 모델을 사용합니다(사실 SDXL 쪽이 이미지 품질이 더 좋지만, 좀 성능이 떨어지는 모델로 생성해야 이 글의 목적을 달성할 수 있기 때문입니다).

프롬프트: Portrait photo of a man

기대했던 대로입니다. 그렇지만, 모두들 좀 심각해 보입니다. 수염을 없애서 좀 밝은 분위를 만들어 보겠습니다.

프롬프트: Portrait photo of a man without mustache

문제가 발생했습니다. 수염을 없애랬더니 훨씬 두드러지게 나타났네요. 무슨일인가요? "without"과 "mustache"을 연관짓는 교차인지(cross-attention)에서 문제가 발생하였을 가능성이 높습니다. 스테이블 디퓨전은 "without"은 이해하지 못하고 프롬프트를 "man"과 "mustache"로 이해한 것입니다.

SDXL을 사용해도 마찬가지네요. 대신 중동쪽 사람들 얼굴이 주로 만들어졌습니다. 이슬람 남성은 반드시 콧수염을 길러야 하기 때문인 듯 합니다.

참고로 프롬프트를 잘 이해한다는 DALL-E 3의 경우, 아래와 같은 이미지를 생성합니다. 분명이 수염이 없는 이라고 입력했는데(Portrait photo of a man without mustache라고 입력해도 마찬가지로) 수염을 깍고 좀 지난 듯한 남자 얼굴만 나오네요. ㅎㅎ

긍정적 프롬프트와 부정적 프롬프트를 함께 사용할 경우

그럼 콧수염이 없는 남자는 어떻게 생성해야 할까요? 그 해답이 부정적 프롬프트(Negative Prompt)입니다. 아래와 같이 프롬프트를 작성합니다.

프롬프트: Portrait photo of a man
부정적 프롬프트: mustache

이렇게 부정적 프롬프트에 mustache를 지정하니, 콧수염이 없는 남자 이미지가 생성되었습니다. SDXL 모델을 사용해도 마찬가지 결과가 나옵니다.

부정적 프롬프트의 원리

예전에 쓴 text-to-image 조건부여에서 프롬프트는 임베딩 벡터로 변환된 후, U-Net 잡음 예측기에 공급된다고 했었습니다. 사실 이게 전부는 아닙니다. 실제로는 두가지 임베딩 벡터가 존재합니다. 하나는 긍정적 프롬프트에 대한 임베딩 벡터, 다른 하나는 부정적 프롬프트에 대한 임베딩 벡터입니다.

긍정적 프롬프트와 부정적 프롬프트는 동등한 위치에 있습니다. 둘다 77개의 토큰으로 치환됩니다. 또한 어느 하나만 있어도 이미지를 생성하는 데 지장이 없습니다(부정적 프롬프트만 있어도 이미지가 생성됩니다)

부정적 프롬프트는 샘플러에서 구현됩니다. 샘플러는 역방향 확산을 구현하는 책임이 있는 알고리즘입니다. 부정적 프롬프트의 작동 방식을 이해하기 위해서는 먼저 부정적 프롬프트 없이 샘플링 작업이 어떻게 이루어지는지 이해할 필요가 있습니다.

부정적 프롬프트가 없는 샘플링

스테이블 디퓨전의 샘플링 단계에서, 알고리즘은 먼저 텍스트 프롬프트로 안내된, 조건부여 샘플링을 사용해 이미지의 잡음을 제거합니다. 그 다음 조건부여없는 샘플링을 사용해서 동일한 이미지의 잡음을 제거합니다.이 두번째 이미지는 텍스트 프롬프트가 없는 것처럼 아무런 조건없이 생성됩니다. 참고로 이 상태에서도 농구공이나 와인잔과 같이(어떤 것이라도 될 수 있습니다) 쓸만한 이미지 쪽으로 역방향 확산이 이루어집니다. 이 두가지 이미지(조건부여(conditional) 이미지와 조건부여가 없는 이미지(unconditional))차이가 역방향 확산 단계의 결과입니다. 이러한 과정이 정해진 샘플링 단계에 이를 때까지 반복됩니다.

부정적 프롬프트가 없는 경우. 확산 단계는 프롬프트에 가까워지고, 무작위 이미지로부터 멀어지는 방향으로 이루어집니다.

부정적 프롬프트가 있는 샘플링

부정적 프롬프트는 조건부여 없는 샘플링을 납치(하이재킹)하는 방식으로 이루어집니다. 프롬프트없이 무작위 이미지로부터 잡음제거를 하는 대신, 부정적 프롬프트를 사용하여 잡음제거를 한다는 뜻입니다.

부정적 프롬프트를 사용하면, 역방향 확산 단계는 프롬프트 쪽으로, 그리고 부정적 프롬프트가 멀어지는 쪽으로 진행됩니다.

기술적으로, 긍정적 프롬프트는 확산 프로세스를 긍정적 프롬프트와 연관된 이미지 쪽으로 이끌어가고, 부정적 프롬프트는 부정적 프롬프트와 연관된 이미지로부터 멀어지는 쪽으로 이끌어갑니다. 참고로, Stable Diffusion의 경우, 확산 프로세스가 이미지 공간이 아닌 잠재 공간(latent space)에서 이루어집니다. 위의 그림들은 이미지 공간에서 표현을 했지만, 예를 들기위한 목적일 뿐입니다. 프로그램 코드수준에서 어떻게 구현되는지 알고 싶으시다면 이 글을 읽어보시기 바랍니다.

샘플링 공간(Sampling Space)

아래의 샘플링 공간 그림을 생각해 보죠. 우리가 "Portrait photo of a man"이라느 프롬프트를 사용하면, 스테이블 디퓨전에서는 수염의 유무에 관계없이 모든 남자에 대한 잠재 공간으로부터 이미지를 샘플링하게 됩니다. 따라서 수염이 있는 이미지도, 없는 이미지도 생성됩니다.

남자에 대한 이미지 공간

부정적 프롬프트 "mustache"를 축가하면, "Men with mustache"가 차지한 공간은 제외됩니다. 따라서 수염이 없는 남자 이미지만 샘플링 됩니다.

요약

부정적 프롬프트는 긍정적 프롬프트만으로는 생성하기 불가능한 방법으로 객체 또는 스타일을 제외시킵니다. 이는 각각의 샘플링 단계에서 조건부여 없는(unconditional) 샘플링을 납치하는 방법으로 구현됩니다. 결국 확산 프로세스튼 부정적 프롬프트에서 기술된 것으로부터 멀어지는 방향으로 이끌어지게 됩니다.

이상입니다. 이 글은 https://stable-diffusion-art.com/how-negative-prompt-work/ 을 번역하여 작성하였습니다.

민, 푸른하늘

====