이전 내용
이미지 생성 AI
이미지 생성 AI란, 인공지능을 사용하여 새로운 이미지를 만들어 내는 기술을 뜻하며, 인공지능이 사용자가 입력한 텍스ㅌ트 설명을 분석하고 이해하여 그 내용에 맞는 이미지를 생성한다. 이 기술은 머신러닝과 적대적 생성 신경망(GANs), 트랜스포머 같은 딥러닝 알고리즘을 사용하여 작동한다.
[적대적 생성 신경망 - GAN]
※ 썸네일에 생성적 적대 신경망이라고 적혀 있는데, 적대적 생성 신경망이 맞는 말이다.
◆ 이미지 생성 인공지능 서비스
대표적인 이미지 생성 AI 서비스에는 달리(DALL-E), 미드저니(Midjourney), 드림스튜디오(DreamStudio), 파이어플라이(Firefly), 노벨AI(NovelAI), 스테이블 디퓨전(Stable Diffusion) 등이 있다.
[각 서비스 사이트]
- 달리3 (DALL-E3): https://openai.com/index/dall-e-3/
- 미드저니: https://www.midjourney.com/home
- 드림스튜디오: https://beta.dreamstudio.ai/generate
- 파이어플라이: https://www.adobe.com/kr/products/firefly.html
- 노벨AI: https://novelai.net/
- 스테이블 디퓨전: https://stablediffusionweb.com/ko
스테이블 디퓨전
스테이블 디퓨전은 Stability AI에서 오픈소스 라이선스로 배포한 이미지 생성 인공지능 모델이다.
스테이블 디퓨전 모델을 사용하는 방법에는
- 깃허브에 올라와 있는 stable-diffusion 모델을 직접 설치
- 허깅페이스에서 Diffusers 프레임워크를 설치해 사용
- comfyUI를 설치해 노드 방식으로 여러 모델을 조합해 사용
- Stable Diffusion web UI를 설치해 사용하는 방법 (가장 많이 사용하는 방법)
등이 있는데, 여기서는 Stable Diffusion API라는 곳에서 API를 호출하여 이미지를 생성하는 방법을 시도해 본다.
스테이블 디퓨전 API
Stable Diffusion API는 스테이블 디퓨전 모델 뿐만 아니라 파생된 여러 형태의 모델을 가져와 쓸 수 있도록 문서가 잘 정리되어 있으며, API를 사용하면 프로그램에 친숙하지 않은 사용자도 약간의 코딩만으로 모델을 사용할 수 있다는 장점과 복잡한 설치를 할 필요가 없고 컴퓨터의 성능이 좋을 필요가 없다는 장점이 있다.
◆ Stable Diffusion API 키 발급하기 (이 아닌 stability.ai API 키 발급 방법이다.)
API를 발급 받기 위해서는 먼저 stability.ai 사이트에 접속하고
[Get Started with API] 버튼을 클릭하고 회원가입을 한다. (필자는 구글 계정 연동)
그리고 스크롤을 내려 [Pricing] 클릭
Pricing 페이지에서 Buying Credits 항목에서 [account page] 링크 클릭
※ 처음 가입하면 이미지를 무료로 생성할 수 있는 25 크레딧을 준다.
필자의 경우는 해당 페이지로 넘어가자마자 API가 자동으로 발급되어 있었는데, 만약 Key가 없다면 [+ Create API Key] 버튼 클릭하여 API Key를 발급 받는다.
그리고 오른쪽에 copy 버튼을 눌러 해당 키를 복사하여 잘 보관한다. (노출 금지)
stability.ai API 키 환경 변수 등록하기
발급받은 stability.ai API Key를 시스템 속성을 통해 변수로 추가한다.
1. '이 PC' 또는 '내 컴퓨터'를 마우스 오른쪽 버튼으로 클릭하고 '속성'을 선택한다. (또는 윈도우 검색 창에서 '시스템 환경변수'를 검색한다.)
2. '고급 시스템 설정'을 클릭.
3. '환경변수' 버튼을 클릭.
4. '시스템 변수' 섹션에서 '새로 만들기...'를 클릭하고 변수 이름으로 SD_API_KEY를 입력하고 변수 값으로 API 키를 입력.
확인 : 설정을 확인하려면 명령 프롬프트를 다시 열고 아래 명령을 입력할 때 API 키가 표시되어야 한다.
echo %SD_API_KEY%
★ 가상 환경으로 주피터노트북을 사용할 경우 API 키 등록
필자처럼 가상 환경으로 주피터노트북을 사용할 경우, 가상 환경에도 해당 키를 등록해 놔야 한다.
먼저, anaconda prompt를 실행한 뒤 가상 환경을 켜고
activate 가상환경명
하단의 명령어를 입력하여 API 키를 설정해준 뒤,
set SD_API_KEY = 'YOUR API KEY'
주피터노트북을 실행한다. (만약 환경 변수명을 변경하고 싶다면 set 새로운 변수 명 = API KEY를 입력하면 된다. 기존 변수 명에 새로운 API KEY를 덮어쓰고 싶을 때도 마찬가지.)
주피터노트북을 켜고, 새로운 셀을 생성한 뒤, 하단의 명령어를 입력하여 Value Error가 뜨지 않는다면 API 키가 환경 변수에 잘 등록되었다는 것을 의미한다.
import os
# 환경변수에서 Stable Diffusion API 키 읽어옴.
sd_api_key = os.getenv('SD_API_KEY')
# API 키가 환경변수에 설정되어 있는지 확인.
if not sd_api_key:
raise ValueError("환경변수 'SD_API_KEY'가 설정되지 않았습니다.")
앞으로 스테이블 디퓨전 API를 사용할 때 필요한 API 키 값은 SD_API_KEY 변수를 대입하여 사용하면 된다.
스테이블 디퓨전 API 사용하기 (주피터노트북)
새로 만든 셀에서 SD API 키를 불러온 후, 본격적으로 스테이블 디퓨전 API를 사용하는 법을 익혀본다.
◆ Text to Image
Text to Image는 텍스트 프롬프트에서 이미지를 생성하는 기능이다. 통신 코드를 작성해 Stable Diffusion API에 요청하면 서버에서 이미지를 생성한 후 생성된 이미지를 확인할 수 있는 링크를 반환한다.
다음은 스테이블 디퓨전 API의 공식 문서에서 제시하는 기본적인 Text to Image 요청 코드의 형태이다.
https://docs.modelslab.com/image-generation/realtime-stable-diffusion/text2img
import requests
import json
url = "https://modelslab.com/api/v6/realtime/text2img"
payload = json.dumps({
"key" : "",
"prompt": "ultra realistic close up portrait ((beautiful pale cyberpunk female with heavy black eyeliner))",
"negative_prompt": "bad quality",
"width": "512",
"height": "512",
"safety_checker": False,
"seed": None,
"samples":1,
"base64":False,
"webhook": None,
"track_id": None
})
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
1. import requests
requests 라이브러리는 파이썬에서 가장 많이 사용하는 통신 라이브러리로, 스테이블 디퓨전 API는 파이썬에서 설치해 사용할 수 있는 전용 모듈이 존재하지 않으므로 requests를 활용하여 API에 요청하도록 권장하고 있다.
따라서, 만약 requests 패키지가 설치되어 있지 않을 경우 설치해야 한다.
# anaconda prompt
pip install requests
# jupyter notebook
!pip install requests
필자의 경우, 이미 설치가 되어 있다.
2. import json
스테이블 디퓨전 API는 API를 요청받을 때 JSON 형태의 데이터를 입력받기를 원하므로, 데이터를 JSON 형태로 바꾸기 위해 JSON 모듈을 불러온다.
3. url = "https://modelslab.com/api/v6/realtime/text2img"
requests로 API 통신을 할 때는 URL이 반드시 필요하다. 브라우저에 URL을 입력하면 특정 웹페이지를 출력하기 위한 데이터를 되돌려 주듯 스테이블 디퓨전 API 통신에서도 어떠한 형태의 데이터를 되돌려 준다.
4. 매개변수
매개변수 | 설명 |
key | API 키는 요청 인증에 사용. |
prompt | 프롬프트는 생성된 이미지에서 원하는 것에 대한 설명을 제공. 주어진 지침에 따라 AI에게 무엇을 만들어야 하는지 알려준다. |
negative_prompt | negative_prompt 는 우리가 이미지에 원하지 않는 것에 대한 설명. 예로는 NSFW 콘텐츠, 왜곡된 얼굴, 품질이 좋지 않은 것 등. |
width | 너비는 생성된 이미지의 크기를 정의. 너비: 1024x1024. |
height | 높이는 생성된 이미지의 크기를 정의. 높이: 1024x1024. |
samples | 응답으로 반환할 샘플 이미지 수. 최대값은 4. |
safety_checker | NSFW 이미지 검사기는 감지된 부적절한 콘텐츠를 빈 이미지로 대체하여 안전하고 적절한 탐색 환경을 유지. 기본값: true, 옵션: true또는 false. |
seed | seed는 결과를 재생성하는 데 사용. 동일한 시드를 제공하면 매번 동일한 이미지가 생성. 난수 시드에는 "null"을 사용. |
base64 | base64 문자열로 응답을 받음. 기본값 : false, 옵션 : true또는false |
webhook | 원활한 통합과 알림을 위해 이미지 생성이 완료된 후 POST API 호출을 수신할 URL을 할당. |
track_id | 트랙 ID는 웹훅 API 호출에 대한 응답으로 반환되며, 이는 웹훅 요청을 식별하는 데 사용. |
5. headers = {'Content-Type': 'application/json'}
requests를 이용해 API를 요청할 때 데이터의 타입을 알려 주는 역할
6. response = requests.request("POST", url, headers=headers, data=payload)
requests 모듈의 request 함수를 이용해 통신을 시작한다. 응답이 도착하면 response 변수에 API 서버로부터 받은 데이터를 저장한다. request 함수의 첫 번째 인수 "POST"는 데이터를 보내는 규칙을 뜻하며, 두 번째 인수에는 위에서 정의한 URL 변수를 할당해 준다. headers와 data 매개변수에는 앞서 정의한 headers와 payload 변수를 대입한다.
7. print(response.text)
통신이 완료되고 곧바로 print 문이 실행된다. 도착한 데이터를 확인하기 위해서는 response의 text 속성 값을 확인한다.
일부 코드를 수정하고 코드를 실행해 본다.
payload = json.dumps({
"key" : sd_api_key, # key 매개변수에 SD_API_KEY가 담겨 있는 sd_api_key 변수 대입
response = requests.request("POST", url, headers=headers, data=payload)
response_data=json.loads(response.text)
print(json.dumps(response_data, indent=4))
- response_data=json.loads(response.text): json.loads 함수로 response.text를 JSON 형태로 바꾸어 response_data에 대입.
- print(json.,dumps(response_data, indent=4): json.dumps 함수를 이용하여 response_data를 보기 쉬운 문자열로 변환하고, indent 매개변수에 4의 값을 대입하여 문자 간의 간격 조절.
★ 필자의 경우, stable diffusion API 키가 아닌, stability.ai API 키를 발급 받았으므로,
(왜냐하면 stable diffusion API를 발급받으려면 카드 등록을 하고 결제를 해야 하는게 귀찮아서...)
코드를 stability.ai 에 맞게 수정하여 다시 진행해 본다.
스테이블 디퓨전 API 사이트에 들어가보니, 현재는 무료 체험이 불가하다고 한다.
하단의 코드는 stability.ai 개발자 플랫폼 사이트(하단 링크)에서 가져온 코드로 코드에 대한 설명은 다음과 같다.
import requests
response = requests.post(
f"https://api.stability.ai/v2beta/stable-image/generate/ultra",
headers={
"authorization": sd_api_key,
"accept": "image/*"
},
files={"none": ''},
data={
"prompt": "Lighthouse on a cliff overlooking the ocean",
"output_format": "webp",
},
)
if response.status_code == 200:
with open("./lighthouse.webp", 'wb') as file:
file.write(response.content)
else:
raise Exception(str(response.json()))
[코드 설명]
-
- URL: 이미지 생성을 위해 stability.ai API의 특정 엔드포인트로 요청을 보낸다.
- https://api.stability.ai/v2beta/stable-image/generate/ultra
- 헤더: 요청 헤더는 두 가지를 포함한다.
- "authorization": sd_api_key: API 키를 인증 토큰으로 사용하여 요청의 정당성을 인증한다.
- "accept": "image/*": 서버가 응답으로 이미지를 보내줄 것을 기대한다.
- 파일: 파일 전송 부분을 비워둔다.
- files={"none": ''}
- 데이터: 요청 데이터는 다음을 포함한다.
- "prompt": "Lighthouse on a cliff overlooking the ocean": 생성될 이미지에 대한 텍스트 설명을 제공한다.
- "output_format": "webp": 출력 형식을 webp로 설정한다.
- URL: 이미지 생성을 위해 stability.ai API의 특정 엔드포인트로 요청을 보낸다.
응답 처리
API 요청에 대해 서버가 응답한 내용을 처리한다.
- 성공적인 응답 (상태 코드 200):
- 응답이 성공적일 경우, 응답 내용(response.content)을 받아 파일로 저장한다.
- with open("./lighthouse.webp", 'wb') as file: 'lighthouse.webp'라는 파일을 바이너리 쓰기 모드로 연다.
- file.write(response.content): 응답 내용(이미지 데이터를 바이너리 형식으로)을 파일에 쓴다.
- 실패한 응답:
- 응답이 성공적이지 않으면, 예외를 발생시킨다.
- raise Exception(str(response.json())): 에러 메시지를 JSON 형식으로 받아 예외를 발생시킨다.
이 코드의 주요 목적은 stability.ai API를 통해 텍스트 프롬프트를 기반으로 이미지를 생성하고, 그 결과 이미지를 webp 형식으로 파일에 저장하는 것이다. 이 과정에서 발생할 수 있는 오류는 예외 처리로 감지할 수 있다.
이 코드를 실행하면 지정한 경로에 webp 확장자 파일이 생성되고, 이를 열어보면 아래와 같은 그림이 나온다.
Lighthouse on a cliff overlooking the ocean: 바다가 내려다보이는 절벽 위의 등대
다음 내용
[출처]
Hey, 파이썬 생성형 AI 활용 앱 만들어줘
스테이블 디퓨전 홈페이지
https://markspeople.tistory.com/140
바로 시작하는 ChatGPT
스테이블 디퓨전 API 공식 문서
stability.ai API 공식 문서
'[파이썬 Projects] > <파이썬 Gen AI>' 카테고리의 다른 글
[Gen AI] 그라디오로 두 번째 챗봇 제작하기-3 (1) | 2024.12.21 |
---|---|
[Gen AI] 그라디오로 두 번째 챗봇 제작하기-2 (1) | 2024.12.21 |
[Gen AI] 그라디오로 두 번째 챗봇 제작하기-1 (1) | 2024.12.20 |
[Gen AI] 문서 요약 프롬프트 제작 (1) | 2024.12.20 |
[Gen AI] 음성 변환 기술 구현해보기(STT, TTS) (1) | 2024.12.19 |