heybaeheef commited on
Commit
8212fa0
ยท
verified ยท
1 Parent(s): 7d6c6f0

Upload 9 files

Browse files
Files changed (1) hide show
  1. main.py +19 -59
main.py CHANGED
@@ -1,17 +1,16 @@
1
  """
2
  MagicPath AI Vocal Effects Server - DiffVox LLM ํ†ตํ•ฉ ๋ฒ„์ „
3
  =========================================================
4
- Dry ๋ณด์ปฌ ํŒŒ์ผ์„ ๋ฐ›์•„์„œ ํ•™์Šต๋œ AI๊ฐ€ ์ดํŽ™ํ„ฐ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์˜ˆ์ธกํ•˜๊ณ ,
5
- ์‹ค์ œ๋กœ ์ดํŽ™ํŠธ๋ฅผ ์ ์šฉํ•œ ์˜ค๋””์˜ค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์„œ๋ฒ„
6
  """
7
 
8
  from fastapi import FastAPI, UploadFile, File, Form, HTTPException
9
  from fastapi.middleware.cors import CORSMiddleware
10
  from fastapi.responses import FileResponse, JSONResponse
 
11
  import tempfile
12
  import os
13
  import uuid
14
- MODEL_PATH = os.environ.get("DIFFVOX_MODEL_PATH", "heybaeheef/KU_SW_Academy/checkpoints")
15
 
16
  # ๋‚ด๋ถ€ ๋ชจ๋“ˆ
17
  from models.ai_effector import AIEffector
@@ -21,12 +20,16 @@ from audio_processing.effect_chain import EffectChain
21
  # ์„ค์ •
22
  # ============================================
23
 
24
- # ํ•™์Šต๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ (Hugging Face ๋ ˆํฌ ๋˜๋Š” ๋กœ์ปฌ ๊ฒฝ๋กœ)
25
- MODEL_PATH = os.environ.get("DIFFVOX_MODEL_PATH", "heybaeheef/KU_SW_Academy")
26
  BASE_MODEL_NAME = os.environ.get("BASE_MODEL_NAME", "Qwen/Qwen3-8B")
27
  AUDIO_FEATURE_DIM = int(os.environ.get("AUDIO_FEATURE_DIM", "64"))
28
  USE_HUGGINGFACE = os.environ.get("USE_HUGGINGFACE", "true").lower() == "true"
29
 
 
 
 
 
30
  # ============================================
31
  # FastAPI ์•ฑ ์ดˆ๊ธฐํ™”
32
  # ============================================
@@ -40,7 +43,7 @@ app = FastAPI(
40
  # CORS ์„ค์ •
41
  app.add_middleware(
42
  CORSMiddleware,
43
- allow_origins=["*"], # ๋ฐฐํฌ ์‹œ ํŠน์ • ๋„๋ฉ”์ธ์œผ๋กœ ์ œํ•œ ๊ถŒ์žฅ
44
  allow_credentials=True,
45
  allow_methods=["*"],
46
  allow_headers=["*"],
@@ -64,10 +67,6 @@ ai_effector = AIEffector(
64
  )
65
  effect_chain = EffectChain()
66
 
67
- # ์ž„์‹œ ํŒŒ์ผ ์ €์žฅ ๊ฒฝ๋กœ
68
- TEMP_DIR = Path(tempfile.gettempdir()) / "magicpath"
69
- TEMP_DIR.mkdir(exist_ok=True)
70
-
71
 
72
  # ============================================
73
  # API ์—”๋“œํฌ์ธํŠธ
@@ -80,9 +79,11 @@ async def root():
80
  "status": "running",
81
  "message": "MagicPath AI Vocal Effects Server v2.0 (DiffVox LLM)",
82
  "ai_model_loaded": ai_effector.is_loaded(),
 
83
  "endpoints": {
84
  "POST /process": "์˜ค๋””์˜ค ํŒŒ์ผ ์ฒ˜๋ฆฌ ํ›„ ๋ฐ˜ํ™˜",
85
  "POST /predict": "ํŒŒ๋ผ๋ฏธํ„ฐ๋งŒ ์˜ˆ์ธก (JSON)",
 
86
  "GET /health": "์„œ๋ฒ„ ์ƒํƒœ ํ™•์ธ"
87
  }
88
  }
@@ -105,28 +106,18 @@ async def predict_parameters(
105
  audio: UploadFile = File(..., description="Dry ๋ณด์ปฌ ์˜ค๋””์˜ค ํŒŒ์ผ"),
106
  prompt: str = Form("", description="ํ…์ŠคํŠธ ๋ช…๋ น (์˜ˆ: 'warm', 'bright')")
107
  ):
108
- """
109
- AI ๋ชจ๋ธ๋กœ ์ดํŽ™ํ„ฐ ํŒŒ๋ผ๋ฏธํ„ฐ ์˜ˆ์ธก (์˜ค๋””์˜ค ์ฒ˜๋ฆฌ ์—†์ด)
110
-
111
- - audio: wav, mp3 ๋“ฑ ์˜ค๋””์˜ค ํŒŒ์ผ
112
- - prompt: ์›ํ•˜๋Š” ์‚ฌ์šด๋“œ ์„ค๋ช…
113
-
114
- Returns: ์˜ˆ์ธก๋œ ์ดํŽ™ํ„ฐ ํŒŒ๋ผ๋ฏธํ„ฐ JSON
115
- """
116
  try:
117
- # ์ž„์‹œ ํŒŒ์ผ๋กœ ์ €์žฅ
118
  input_path = TEMP_DIR / f"{uuid.uuid4()}_{audio.filename}"
119
  with open(input_path, "wb") as f:
120
  content = await audio.read()
121
  f.write(content)
122
 
123
- # AI ๋ชจ๋ธ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ ์˜ˆ์ธก
124
  parameters = ai_effector.predict(
125
  audio_path=str(input_path),
126
  text_prompt=prompt
127
  )
128
 
129
- # ์ž„์‹œ ํŒŒ์ผ ์‚ญ์ œ
130
  os.remove(input_path)
131
 
132
  return JSONResponse(content={
@@ -145,50 +136,32 @@ async def process_audio(
145
  audio: UploadFile = File(..., description="Dry ๋ณด์ปฌ ์˜ค๋””์˜ค ํŒŒ์ผ"),
146
  prompt: str = Form("", description="ํ…์ŠคํŠธ ๋ช…๋ น (์˜ˆ: 'warm', 'bright')")
147
  ):
148
- """
149
- AI๊ฐ€ ์˜ˆ์ธกํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์‹ค์ œ ์˜ค๋””์˜ค ์ฒ˜๋ฆฌ
150
-
151
- - audio: wav, mp3 ๋“ฑ ์˜ค๋””์˜ค ํŒŒ์ผ
152
- - prompt: ์›ํ•˜๋Š” ์‚ฌ์šด๋“œ ์„ค๋ช…
153
-
154
- Returns: ์ฒ˜๋ฆฌ๋œ ์˜ค๋””์˜ค ํŒŒ์ผ (wav)
155
- """
156
  input_path = None
157
  output_path = None
158
 
159
  try:
160
- # ์ž„์‹œ ํŒŒ์ผ ๊ฒฝ๋กœ ์ƒ์„ฑ
161
  file_id = str(uuid.uuid4())
162
  input_path = TEMP_DIR / f"{file_id}_input_{audio.filename}"
163
  output_path = TEMP_DIR / f"{file_id}_output.wav"
164
 
165
- # ์ž…๋ ฅ ํŒŒ์ผ ์ €์žฅ
166
  with open(input_path, "wb") as f:
167
  content = await audio.read()
168
  f.write(content)
169
 
170
- print(f"[Process] ์ž…๋ ฅ ํŒŒ์ผ: {input_path}")
171
- print(f"[Process] ํ”„๋กฌํ”„ํŠธ: {prompt}")
172
-
173
- # Step 1: AI ๋ชจ๋ธ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ ์˜ˆ์ธก
174
  parameters = ai_effector.predict(
175
  audio_path=str(input_path),
176
  text_prompt=prompt
177
  )
178
 
179
- print(f"[Process] ์˜ˆ์ธก๋œ ํŒŒ๋ผ๋ฏธํ„ฐ: {len(parameters)}๊ฐœ")
180
-
181
- # Step 2: ์ดํŽ™ํ„ฐ ์ฒด์ธ๏ฟฝ๏ฟฝ๏ฟฝ๋กœ ์˜ค๋””์˜ค ์ฒ˜๋ฆฌ
182
  effect_chain.process(
183
  input_path=str(input_path),
184
  output_path=str(output_path),
185
  parameters=parameters
186
  )
187
 
188
- # ์ž…๋ ฅ ํŒŒ์ผ ์‚ญ์ œ
189
  os.remove(input_path)
190
 
191
- # ์ฒ˜๋ฆฌ๋œ ์˜ค๋””์˜ค ๋ฐ˜ํ™˜
192
  return FileResponse(
193
  path=str(output_path),
194
  media_type="audio/wav",
@@ -197,15 +170,10 @@ async def process_audio(
197
  )
198
 
199
  except Exception as e:
200
- # ์—๋Ÿฌ ์‹œ ์ž„์‹œ ํŒŒ์ผ ์ •๋ฆฌ
201
- if input_path and input_path.exists():
202
  os.remove(input_path)
203
- if output_path and output_path.exists():
204
  os.remove(output_path)
205
-
206
- print(f"[Process] โŒ ์—๋Ÿฌ: {e}")
207
- import traceback
208
- traceback.print_exc()
209
  raise HTTPException(status_code=500, detail=str(e))
210
 
211
 
@@ -214,11 +182,7 @@ async def process_audio_with_params(
214
  audio: UploadFile = File(..., description="Dry ๋ณด์ปฌ ์˜ค๋””์˜ค ํŒŒ์ผ"),
215
  prompt: str = Form("", description="ํ…์ŠคํŠธ ๋ช…๋ น")
216
  ):
217
- """
218
- ์˜ค๋””์˜ค ์ฒ˜๋ฆฌ + ์‚ฌ์šฉ๋œ ํŒŒ๋ผ๋ฏธํ„ฐ๋„ ํ•จ๊ป˜ ๋ฐ˜ํ™˜
219
-
220
- Returns: JSON (์ฒ˜๋ฆฌ๋œ ์˜ค๋””์˜ค URL + ํŒŒ๋ผ๋ฏธํ„ฐ)
221
- """
222
  input_path = None
223
  output_path = None
224
 
@@ -231,13 +195,11 @@ async def process_audio_with_params(
231
  content = await audio.read()
232
  f.write(content)
233
 
234
- # AI ํŒŒ๋ผ๋ฏธํ„ฐ ์˜ˆ์ธก
235
  parameters = ai_effector.predict(
236
  audio_path=str(input_path),
237
  text_prompt=prompt
238
  )
239
 
240
- # ์˜ค๋””์˜ค ์ฒ˜๋ฆฌ
241
  effect_chain.process(
242
  input_path=str(input_path),
243
  output_path=str(output_path),
@@ -246,8 +208,6 @@ async def process_audio_with_params(
246
 
247
  os.remove(input_path)
248
 
249
- # Base64 ์ธ์ฝ”๋”ฉ์œผ๋กœ ์˜ค๋””์˜ค ๋ฐ˜ํ™˜ (๋˜๋Š” URL)
250
- import base64
251
  with open(output_path, "rb") as f:
252
  audio_base64 = base64.b64encode(f.read()).decode('utf-8')
253
 
@@ -263,13 +223,13 @@ async def process_audio_with_params(
263
  })
264
 
265
  except Exception as e:
266
- if input_path and input_path.exists():
267
  os.remove(input_path)
268
- if output_path and output_path.exists():
269
  os.remove(output_path)
270
  raise HTTPException(status_code=500, detail=str(e))
271
 
272
 
273
  if __name__ == "__main__":
274
  import uvicorn
275
- uvicorn.run(app, host="0.0.0.0", port=8000)
 
1
  """
2
  MagicPath AI Vocal Effects Server - DiffVox LLM ํ†ตํ•ฉ ๋ฒ„์ „
3
  =========================================================
 
 
4
  """
5
 
6
  from fastapi import FastAPI, UploadFile, File, Form, HTTPException
7
  from fastapi.middleware.cors import CORSMiddleware
8
  from fastapi.responses import FileResponse, JSONResponse
9
+ from pathlib import Path
10
  import tempfile
11
  import os
12
  import uuid
13
+ import base64
14
 
15
  # ๋‚ด๋ถ€ ๋ชจ๋“ˆ
16
  from models.ai_effector import AIEffector
 
20
  # ์„ค์ •
21
  # ============================================
22
 
23
+ # ํ•™์Šต๋œ ๋ชจ๋ธ ๊ฒฝ๋กœ - checkpoints ํด๋” ํฌํ•จ!
24
+ MODEL_PATH = os.environ.get("DIFFVOX_MODEL_PATH", "heybaeheef/KU_SW_Academy/checkpoints")
25
  BASE_MODEL_NAME = os.environ.get("BASE_MODEL_NAME", "Qwen/Qwen3-8B")
26
  AUDIO_FEATURE_DIM = int(os.environ.get("AUDIO_FEATURE_DIM", "64"))
27
  USE_HUGGINGFACE = os.environ.get("USE_HUGGINGFACE", "true").lower() == "true"
28
 
29
+ # ์ž„์‹œ ํŒŒ์ผ ์ €์žฅ ๊ฒฝ๋กœ - ๋จผ์ € ์ •์˜
30
+ TEMP_DIR = Path(tempfile.gettempdir()) / "magicpath"
31
+ TEMP_DIR.mkdir(exist_ok=True)
32
+
33
  # ============================================
34
  # FastAPI ์•ฑ ์ดˆ๊ธฐํ™”
35
  # ============================================
 
43
  # CORS ์„ค์ •
44
  app.add_middleware(
45
  CORSMiddleware,
46
+ allow_origins=["*"],
47
  allow_credentials=True,
48
  allow_methods=["*"],
49
  allow_headers=["*"],
 
67
  )
68
  effect_chain = EffectChain()
69
 
 
 
 
 
70
 
71
  # ============================================
72
  # API ์—”๋“œํฌ์ธํŠธ
 
79
  "status": "running",
80
  "message": "MagicPath AI Vocal Effects Server v2.0 (DiffVox LLM)",
81
  "ai_model_loaded": ai_effector.is_loaded(),
82
+ "model_path": MODEL_PATH,
83
  "endpoints": {
84
  "POST /process": "์˜ค๋””์˜ค ํŒŒ์ผ ์ฒ˜๋ฆฌ ํ›„ ๋ฐ˜ํ™˜",
85
  "POST /predict": "ํŒŒ๋ผ๋ฏธํ„ฐ๋งŒ ์˜ˆ์ธก (JSON)",
86
+ "POST /process_with_params": "์˜ค๋””์˜ค ์ฒ˜๋ฆฌ + ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ˜ํ™˜",
87
  "GET /health": "์„œ๋ฒ„ ์ƒํƒœ ํ™•์ธ"
88
  }
89
  }
 
106
  audio: UploadFile = File(..., description="Dry ๋ณด์ปฌ ์˜ค๋””์˜ค ํŒŒ์ผ"),
107
  prompt: str = Form("", description="ํ…์ŠคํŠธ ๋ช…๋ น (์˜ˆ: 'warm', 'bright')")
108
  ):
109
+ """AI ๋ชจ๋ธ๋กœ ์ดํŽ™ํ„ฐ ํŒŒ๋ผ๋ฏธํ„ฐ ์˜ˆ์ธก"""
 
 
 
 
 
 
 
110
  try:
 
111
  input_path = TEMP_DIR / f"{uuid.uuid4()}_{audio.filename}"
112
  with open(input_path, "wb") as f:
113
  content = await audio.read()
114
  f.write(content)
115
 
 
116
  parameters = ai_effector.predict(
117
  audio_path=str(input_path),
118
  text_prompt=prompt
119
  )
120
 
 
121
  os.remove(input_path)
122
 
123
  return JSONResponse(content={
 
136
  audio: UploadFile = File(..., description="Dry ๋ณด์ปฌ ์˜ค๋””์˜ค ํŒŒ์ผ"),
137
  prompt: str = Form("", description="ํ…์ŠคํŠธ ๋ช…๋ น (์˜ˆ: 'warm', 'bright')")
138
  ):
139
+ """AI๊ฐ€ ์˜ˆ์ธกํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์‹ค์ œ ์˜ค๋””์˜ค ์ฒ˜๋ฆฌ"""
 
 
 
 
 
 
 
140
  input_path = None
141
  output_path = None
142
 
143
  try:
 
144
  file_id = str(uuid.uuid4())
145
  input_path = TEMP_DIR / f"{file_id}_input_{audio.filename}"
146
  output_path = TEMP_DIR / f"{file_id}_output.wav"
147
 
 
148
  with open(input_path, "wb") as f:
149
  content = await audio.read()
150
  f.write(content)
151
 
 
 
 
 
152
  parameters = ai_effector.predict(
153
  audio_path=str(input_path),
154
  text_prompt=prompt
155
  )
156
 
 
 
 
157
  effect_chain.process(
158
  input_path=str(input_path),
159
  output_path=str(output_path),
160
  parameters=parameters
161
  )
162
 
 
163
  os.remove(input_path)
164
 
 
165
  return FileResponse(
166
  path=str(output_path),
167
  media_type="audio/wav",
 
170
  )
171
 
172
  except Exception as e:
173
+ if input_path and Path(input_path).exists():
 
174
  os.remove(input_path)
175
+ if output_path and Path(output_path).exists():
176
  os.remove(output_path)
 
 
 
 
177
  raise HTTPException(status_code=500, detail=str(e))
178
 
179
 
 
182
  audio: UploadFile = File(..., description="Dry ๋ณด์ปฌ ์˜ค๋””์˜ค ํŒŒ์ผ"),
183
  prompt: str = Form("", description="ํ…์ŠคํŠธ ๋ช…๋ น")
184
  ):
185
+ """์˜ค๋””์˜ค ์ฒ˜๋ฆฌ + ์‚ฌ์šฉ๋œ ํŒŒ๋ผ๋ฏธํ„ฐ๋„ ํ•จ๊ป˜ ๋ฐ˜ํ™˜"""
 
 
 
 
186
  input_path = None
187
  output_path = None
188
 
 
195
  content = await audio.read()
196
  f.write(content)
197
 
 
198
  parameters = ai_effector.predict(
199
  audio_path=str(input_path),
200
  text_prompt=prompt
201
  )
202
 
 
203
  effect_chain.process(
204
  input_path=str(input_path),
205
  output_path=str(output_path),
 
208
 
209
  os.remove(input_path)
210
 
 
 
211
  with open(output_path, "rb") as f:
212
  audio_base64 = base64.b64encode(f.read()).decode('utf-8')
213
 
 
223
  })
224
 
225
  except Exception as e:
226
+ if input_path and Path(input_path).exists():
227
  os.remove(input_path)
228
+ if output_path and Path(output_path).exists():
229
  os.remove(output_path)
230
  raise HTTPException(status_code=500, detail=str(e))
231
 
232
 
233
  if __name__ == "__main__":
234
  import uvicorn
235
+ uvicorn.run(app, host="0.0.0.0", port=7860)