안녕하세요 ^^ HuggingFace 캠프 파트너 정정민입니다.
이전 포스팅에서는 Inference API를 설명 드렸는데요,
이번에는 본인의 컴퓨터에서 실행시키는 Local 추론 과정을 설명드리며
이 둘의 장단점을 살펴보려고 합니다 ^^
준비
이번 실습에서 사용할 HuggingFace Model 페이지는 facebook/musicgen-small에 있습니다
간단히 설명드리면
2023년 Facebook에서 연구한 결과물로
텍스트 프롬프트를 기반으로
음악을 만들어주는 모델입니다 🤩
Inference API 사용
이전 포스팅에서 살펴본 대로 Inference API 코드를 가져옵니다.
import requests
API_URL = "https://api-inference.huggingface.co/models/facebook/musicgen-small"
headers = {"Authorization": f"Bearer {HF_API}"}
def query(payload):
response = requests.post(API_URL, headers=headers, json=payload)
return response.content
audio_bytes = query({
"inputs": "liquid drum and bass, atmospheric synths, airy sounds",
})
모든 모델의 결과가 다 같은 형태는 아니겠지만, 이 예시에서의 결과는 bytes의 형태 더라구요.
bytes니까 바로 write로 저장해버립니다!
with open('musicgen_out.mp3', 'wb') as file:
file.write(audio_bytes)
"liquid drum and bass, atmospheric synths, airy sounds" 이런 느낌이 나는지 결과를 들어볼까요??
musicgen_out.mp3추론 시간
사실 API는 추론 시간이 굉장히 중요합니다.
특히 인터넷을 통해 소통을 하니 이 부분은 항상 확인해야하는 파트죠.
딱 쿼리만 던지는 부분으로 시간을 측정해봅니다.
%%timeit
query({
"inputs": "liquid drum and bass, atmospheric synths, airy sounds",
})
# 4.06 s ± 481 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
timeit 매직 키워드의 결과를 보면
7번의 시도를 했고 평균 4.06초, 표준편차 0.481초 정도로 준수한 속도가 나온다고 합니다.
몇 번 사용 경험에 따르면 저정도 속도면 나쁜 속도는 아닙니다.
대신 인터넷 상황, 제공하는 연구소 서버 이슈 등으로 속도의 등락은 충분히 있을 수 있죠!!
그러다 문제를 하나 발견합니다.
5개의 prompt를 리스트로 만들어 for 문으로 추론하다 보니 아래와 같은 에러를 받았습니다.
아무래도 여러 사람들이 사용하는 만큼 이런 불안정성이 있을 수 있다고 봅니다.
{"error":"Service Unavailable"}
{"error":"Model facebook/musicgen-small is currently loading","estimated_time":94.57394409179688}
Local Model 사용
Model 페이지를 보면 Local에서 모델을 사용할 수 있는 방법을 잘 정리해줍니다.
이번 실습에 사용하는 페이지도 있네요 !! 링크
from transformers import AutoProcessor, MusicgenForConditionalGeneration
processor = AutoProcessor.from_pretrained("facebook/musicgen-small")
model = MusicgenForConditionalGeneration.from_pretrained("facebook/musicgen-small")
inputs = processor(
text=["80s pop track with bassy drums and synth", "90s rock song with loud guitars and heavy drums"],
padding=True,
return_tensors="pt",
)
audio_values = model.generate(**inputs, max_new_tokens=256)
processor : 데이터 전처리 과정입니다. 입력으로 넣어주는 text 정보와 메타 정보를 활용해 모델이 넣어줄 준비를 합니다.
model : 모델의 이름을 기반으로 학습된 모델을 불러오고 저장합니다 ("facebook/musicgen-small")
Local model 크기 계산
딥러닝 모델은 그 내부에 존재하는 연산 대상 객체(parameters)의 수 만큼 크기를 갖습니다.
이 모델을 계산해보면 약 2.2GB 정도 됩니다.
total_params = sum(p.numel() for p in model.parameters())
total_size_bytes = total_params * 4 # float32 : 4 bytes
total_size_mb = total_size_bytes / (1024 ** 3) # GB
print(f"Total parameters: {total_params}") # Total parameters: 588981826
print(f"Model size: {total_size_mb:.4f} GB") # Model size: 2.1941 GB
이정도면 저장하고 있는 크기 치고는 나쁘지 않죠?
대신 실제 모델을 활용한다면 CPU에 혹은 GPU에 저 만큼의 크기가 올라가니 컴퓨터 상황을 잘 봐야곘네요!
추론 시간
Local 모델은 인터넷 사용이 없어도 되고 안정성이 있다는 장점이 있죠?
그럼 추론 시간은 얼마나 될까요.
같은 방법으로 확인해봅니다.
%%timeit
model.generate(**inputs, max_new_tokens=256)
# 29 s ± 425 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
오우.. 4초 정도 걸린 API 사용보다 시간이 7배나 걸립니다 ㅠㅠ
아무래도 CPU로 사용해서 그런가봅니다.
Colab을 사용해 GPU에서 돌려보죠 (M3 GPU에서는 호환이 안되는 모듈이 아직 많네요ㅠㅠ)
%%timeit
model.generate(**inputs, max_new_tokens=256) # colab GPU T4
# 5.65 s ± 285 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
속도가 빨라지고 API 만큼의 속도가 나옵니다!
아무래도 비슷한 정도의 GPU를 사용한 것 같습니다.
만약 Local에서 GPU로 사용한다면 엄청 메리트가 크겠네요 ^^
정리
제가 본 Inference API와 Local 추론의 특징은 다음과 같습니다.
Inference API
장점 : 속도가 빠르고 로컬 컴퓨터에 부담이 적다
단점 : 간헐적 불안정성
인터넷과 서버 상태에 의존적이며, 간혹 호출 과정에서 응답이 잘 안올 수 있다.
Local 추론
장점 : 안정적
단점
CPU 사용시 속도가 느리다
저장하기 위한 공간, 사용하기위한 공간이 필요 : PC 상황에 의존적 (메모리 계산 필요!)
적고보니 Local 추론의 단점이 많아보이네요 ^^;;
마지막으로 Local 환경에서 만들어낸 음악을 한번 감상해보죠!
"liquid drum and bass, atmospheric synths, airy sounds"
musicgen_local_out_0.wav"hard rock, electric guitar, fast drums"
musicgen_local_out_1.wav"classical piano, violin, orchestral"
musicgen_local_out_2.wav"hip hop, trap beat, rap"
musicgen_local_out_3.wav"Acoustic folk, gentle fingerpicked guitars, soft flutes, and ambient nature sounds"
musicgen_local_out_4.wav감사합니다!
#9기HuggingFace
작성자 : 정정민
블로그 : 링크