yongyeol commited on
Commit
2a55caa
·
verified ·
1 Parent(s): 6dbe26c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -18
app.py CHANGED
@@ -5,45 +5,73 @@ from transformers import (
5
  )
6
  from PIL import Image
7
 
8
- # ── 환경 변수 ────────────────────────────────────────────────
 
 
9
  os.environ["HF_FORCE_SAFE_SERIALIZATION"] = "1"
10
  os.environ["XFORMERS_FORCE_DISABLE"] = "1" # audiocraft 내부 플래그
11
 
12
- # ── xformers 더미 모듈 ───────────────────────────────────────
 
 
13
  dummy = types.ModuleType("xformers")
14
  dummy.__version__ = "0.0.0"
15
  ops = types.ModuleType("xformers.ops")
16
 
17
- def _fake_mem_eff_attn(q, k, v, *_, dropout_p: float = 0.0, **__):
 
18
  return torch.nn.functional.scaled_dot_product_attention(
19
  q, k, v, dropout_p=dropout_p, is_causal=False
20
  )
21
- class _FakeLowerTriangularMask: pass
22
 
23
- ops.memory_efficient_attention = _fake_mem_eff_attn
 
 
 
 
24
  ops.LowerTriangularMask = _FakeLowerTriangularMask
25
  dummy.ops = ops
26
  sys.modules["xformers"] = dummy
27
  sys.modules["xformers.ops"] = ops
28
- # ────────────────────────────────────────────────────────────
29
 
30
- # ── audiocraft 로드 (postInstall에서 이미 설치됐음) ───────────
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  try:
32
  from audiocraft.models import MusicGen
33
  from audiocraft.data.audio import audio_write
34
- except ModuleNotFoundError: # 예외적 로컬 실행 대비
 
35
  subprocess.check_call([
36
  sys.executable, "-m", "pip", "install",
37
  "git+https://github.com/facebookresearch/audiocraft@main",
38
  "--no-deps", "--use-pep517"
39
  ])
 
 
 
 
40
  from audiocraft.models import MusicGen
41
  from audiocraft.data.audio import audio_write
42
 
43
- # ── 이미지 캡셔닝 모델 ─────────────────────────────────────
 
 
44
  caption_model = VisionEncoderDecoderModel.from_pretrained(
45
  "nlpconnect/vit-gpt2-image-captioning",
46
- use_safetensors=True, low_cpu_mem_usage=True
 
47
  )
48
  feature_extractor = ViTImageProcessor.from_pretrained(
49
  "nlpconnect/vit-gpt2-image-captioning"
@@ -52,18 +80,22 @@ tokenizer = AutoTokenizer.from_pretrained(
52
  "nlpconnect/vit-gpt2-image-captioning"
53
  )
54
 
55
- # ── MusicGen 모델 ──────────────────────────────────────────
 
 
56
  musicgen = MusicGen.get_pretrained("facebook/musicgen-small")
57
- musicgen.set_generation_params(duration=10)
58
 
59
- # ── 파이프라인 함수들 ──────────────────────────────────────
 
 
60
  def generate_caption(image: Image.Image) -> str:
61
  pixel_values = feature_extractor(images=image, return_tensors="pt").pixel_values
62
  ids = caption_model.generate(pixel_values, max_length=50)
63
  return tokenizer.decode(ids[0], skip_special_tokens=True)
64
 
65
  def generate_music(prompt: str) -> str:
66
- wav = musicgen.generate([prompt])
67
  tmpdir = tempfile.mkdtemp()
68
  path = os.path.join(tmpdir, "musicgen.wav")
69
  audio_write(path, wav[0], musicgen.sample_rate, strategy="loudness")
@@ -71,10 +103,12 @@ def generate_music(prompt: str) -> str:
71
 
72
  def process(image: Image.Image):
73
  caption = generate_caption(image)
74
- path = generate_music(f"A cheerful melody inspired by: {caption}")
75
  return caption, path
76
 
77
- # ── Gradio UI ──────────────────────────────────────────────
 
 
78
  demo = gr.Interface(
79
  fn=process,
80
  inputs=gr.Image(type="pil"),
@@ -82,8 +116,8 @@ demo = gr.Interface(
82
  gr.Text(label="AI가 생성한 그림 설명"),
83
  gr.Audio(label="생성된 AI 음악 (MusicGen)")
84
  ],
85
- title="🎨 AI 그림‑음악 생성기",
86
- description="그림을 업로드하면 AI가 설명을 만들고, 설명을 바탕으로 음악을 10초간 생성해 들려줍니다."
87
  )
88
 
89
  if __name__ == "__main__":
 
5
  )
6
  from PIL import Image
7
 
8
+ # ─────────────────────────────────────────────────────────────
9
+ # 0. 환경 변수
10
+ # ─────────────────────────────────────────────────────────────
11
  os.environ["HF_FORCE_SAFE_SERIALIZATION"] = "1"
12
  os.environ["XFORMERS_FORCE_DISABLE"] = "1" # audiocraft 내부 플래그
13
 
14
+ # ─────────────────────────────────────────────────────────────
15
+ # 1. xformers 더미 모듈 주입 (GPU 종속 제거)
16
+ # ─────────────────────────────────────────────────────────────
17
  dummy = types.ModuleType("xformers")
18
  dummy.__version__ = "0.0.0"
19
  ops = types.ModuleType("xformers.ops")
20
 
21
+ def _fake_mea(q, k, v, *_, dropout_p: float = 0.0, **__):
22
+ # PyTorch 2.x 표준 S-DPA로 대체 (CPU에서도 동작)
23
  return torch.nn.functional.scaled_dot_product_attention(
24
  q, k, v, dropout_p=dropout_p, is_causal=False
25
  )
 
26
 
27
+ class _FakeLowerTriangularMask:
28
+ """audiocraft가 타입 존재만 확인하므로 빈 클래스로 대체"""
29
+ pass
30
+
31
+ ops.memory_efficient_attention = _fake_mea
32
  ops.LowerTriangularMask = _FakeLowerTriangularMask
33
  dummy.ops = ops
34
  sys.modules["xformers"] = dummy
35
  sys.modules["xformers.ops"] = ops
 
36
 
37
+ # ─────────────────────────────────────────────────────────────
38
+ # 2. 기타 누락 모듈에 대한 더미(stub) 안전망
39
+ # (requirements.txt 에 이미 설치하지만, 혹시 빠져도 런타임 통과)
40
+ # ─────────────────────────────────────────────────────────────
41
+ for name in (
42
+ "av", "librosa", "torchdiffeq", "torchmetrics",
43
+ "pesq", "pystoi", "soxr"
44
+ ):
45
+ if name not in sys.modules:
46
+ sys.modules[name] = types.ModuleType(name)
47
+
48
+ # ─────────────────────────────────────────────────────────────
49
+ # 3. audiocraft (MusicGen) 불러오기
50
+ # ─────────────────────────────────────────────────────────────
51
  try:
52
  from audiocraft.models import MusicGen
53
  from audiocraft.data.audio import audio_write
54
+ except ModuleNotFoundError:
55
+ # 로컬 실행 등으로 미설치 시: 의존성 없는 형태로 설치
56
  subprocess.check_call([
57
  sys.executable, "-m", "pip", "install",
58
  "git+https://github.com/facebookresearch/audiocraft@main",
59
  "--no-deps", "--use-pep517"
60
  ])
61
+ # 필요 최소 의존성만 즉석 설치 (stub로도 대부분 통과하지만 안전하게)
62
+ subprocess.check_call([sys.executable, "-m", "pip", "install",
63
+ "encodec", "torchdiffeq", "torchmetrics",
64
+ "librosa", "soxr", "av"])
65
  from audiocraft.models import MusicGen
66
  from audiocraft.data.audio import audio_write
67
 
68
+ # ─────────────────────────────────────────────────────────────
69
+ # 4. 이미지 캡셔닝 모델
70
+ # ─────────────────────────────────────────────────────────────
71
  caption_model = VisionEncoderDecoderModel.from_pretrained(
72
  "nlpconnect/vit-gpt2-image-captioning",
73
+ use_safetensors=True,
74
+ low_cpu_mem_usage=True
75
  )
76
  feature_extractor = ViTImageProcessor.from_pretrained(
77
  "nlpconnect/vit-gpt2-image-captioning"
 
80
  "nlpconnect/vit-gpt2-image-captioning"
81
  )
82
 
83
+ # ─────────────────────────────────────────────────────────────
84
+ # 5. MusicGen 모델 (CPU 전용)
85
+ # ─────────────────────────────────────────────────────────────
86
  musicgen = MusicGen.get_pretrained("facebook/musicgen-small")
87
+ musicgen.set_generation_params(duration=10) # 10초 길이
88
 
89
+ # ─────────────────────────────────────────────────────────────
90
+ # 6. 파이프라인 함수
91
+ # ─────────────────────────────────────────────────────────────
92
  def generate_caption(image: Image.Image) -> str:
93
  pixel_values = feature_extractor(images=image, return_tensors="pt").pixel_values
94
  ids = caption_model.generate(pixel_values, max_length=50)
95
  return tokenizer.decode(ids[0], skip_special_tokens=True)
96
 
97
  def generate_music(prompt: str) -> str:
98
+ wav = musicgen.generate([prompt]) # batch size = 1
99
  tmpdir = tempfile.mkdtemp()
100
  path = os.path.join(tmpdir, "musicgen.wav")
101
  audio_write(path, wav[0], musicgen.sample_rate, strategy="loudness")
 
103
 
104
  def process(image: Image.Image):
105
  caption = generate_caption(image)
106
+ path = generate_music(f"A cheerful melody inspired by: {caption}")
107
  return caption, path
108
 
109
+ # ─────────────────────────────────────────────────────────────
110
+ # 7. Gradio UI
111
+ # ─────────────────────────────────────────────────────────────
112
  demo = gr.Interface(
113
  fn=process,
114
  inputs=gr.Image(type="pil"),
 
116
  gr.Text(label="AI가 생성한 그림 설명"),
117
  gr.Audio(label="생성된 AI 음악 (MusicGen)")
118
  ],
119
+ title="🎨 AI 그림-음악 생성기",
120
+ description="그림을 업로드하면 AI가 설명을 만들고, 설명을 바탕으로 10초 길이의 음악을 생성해 들려줍니다."
121
  )
122
 
123
  if __name__ == "__main__":