FLUX.1 Controlnet 사용하기
요즘 핫한 FLUX 모델에 Controlnet 적용해보자.
실습은,
FLUX.1-dev 모델을 통해 이미지를 생성하고 생성된 이미지를 통해 Controlnet을 적용해볼 예정이다.
Docker를 이용하여 환경을 구축할 예정이다.
※ webui forge, comfyui 예제는 많이 보이지만 diffusers 형식으로 된 예제는 없길래 직접 만들어본다..
1. Install
# docker 실행
# nvidia에서 제공되는 24.05 기준으로 도커 컨테이너를 만들어 실습할 예정이다.
# mount는 위치는 자신에 알맞게 잘 셋팅한다 -v 자신폴더:/workspace
docker run --name flux --gpus "device=0" -it -v /mydisk:/workspace nvcr.io/nvidia/pytorch:24.05-py3
# 컨테이너 안
apt update -y
apt install -y python3-tk
pip install --upgrade pip
# flux repo 다운로드
git clone https://github.com/black-forest-labs/flux.git
# flux 경로 이동
cd flux
# 패키지 설치
pip install -e '.[all]'
pip install git+https://github.com/huggingface/diffusers.git
pip install accelerate
pip install opencv-python==4.8.0.74
여기까지 진행하면 필요 패키지는 다 설치됐을 것이다.
2. FLUX.1 [dev] 이미지 생성
여기서 dev 버전은 non-commercial license 이므로 상용화는 불가능하다.
여기서는 이것저것 테스트해볼 것이므로..
# flux_generation.py
import torch
from diffusers import FluxPipeline
model_id = "black-forest-labs/FLUX.1-dev"
# 로컬 경로에 weight를 받을 예정이므로 cache_dir를 이용한다. 적절히 자신 경로에 맞게 수정하면 될 것이다.
pipe = FluxPipeline.from_pretrained("black-forest-labs/FLUX.1-dev", torch_dtype=torch.bfloat16, local_files_only=True, cache_dir='./weights/')
pipe.enable_model_cpu_offload() #save some VRAM by offloading the model to CPU. Remove this if you have enough GPU power
prompt = "A cat holding a sign that says hello world"
seed = 42
image = pipe(
prompt,
output_type="pil",
num_inference_steps=4, #use a larger number if you are using [dev]
generator=torch.Generator("cpu").manual_seed(seed)
).images[0]
image.save("flux_img.png")
flux_generation.py 파일을 만들고 위 코드를 넣은 후 python flux_generation.py 실행
그러면 현재 경로에 (/workspace/flux/) 에 flux_img.png 이미지가 저장되어 있을 것이다.

생성된 결과 이미지를 보면 꽤 퀄리티가 좋을것을 볼 수 있다.
그럼 이 이미지를 Controlnet canny를 통해 강아지로 변경해보자.
3. Controlnet 적용
# canny_flux.py
import torch
from diffusers.utils import load_image
from diffusers.pipelines.flux.pipeline_flux_controlnet import FluxControlNetPipeline
from diffusers.models.controlnet_flux import FluxControlNetModel
# 여기서도 마찬가지로 weights 경로를 weights 폴더 안에 저장한다.
base_model = 'black-forest-labs/FLUX.1-dev'
controlnet_model = 'InstantX/FLUX.1-dev-Controlnet-Canny'
controlnet = FluxControlNetModel.from_pretrained(controlnet_model, torch_dtype=torch.bfloat16, local_files_only=True, cache_dir='./weights/')
pipe = FluxControlNetPipeline.from_pretrained(base_model, controlnet=controlnet, torch_dtype=torch.bfloat16, local_files_only=True, cache_dir='./weights/')
pipe.to("cuda")
control_image = load_image("./flux_img.png")
prompt = "A dog holding a sign that says hello world"
image = pipe(
prompt,
control_image=control_image,
controlnet_conditioning_scale=0.6,
num_inference_steps=28,
guidance_scale=3.5,
).images[0]
image.save("flux_controlnet.jpg")
canny_flux.py 파일을 만들고 위 코드를 넣은 후 python canny_flux.py 실행
그러면 현재 경로에 (/workspace/flux/) 에 flux_controlnet.jpg 이미지가 저장되어 있을 것이다.
여기서 prompt를 확인해보면 다양하게 바꿔가면서 테스트해볼 수 있다.
canny가 적용된 결과를 살펴보자.

퀄리티가 꽤나 좋은것을 확인할 수 있다.
Ref.
https://huggingface.co/black-forest-labs/FLUX.1-dev