[MLOps ์šด์˜ ๊ณ ๋„ํ™” - 6๋‹จ๊ณ„: GitOps ๊ณ ๋„ํ™” (Argo CDยทMetalLBยทApplicationSet)]

์ด ๊ธ€์—์„œ ๋‹ค๋ฃจ๋Š” ๊ฒƒ ArgoCD ApplicationSet์œผ๋กœ dev/prod ํ™˜๊ฒฝ์„ ๋‹จ์ผ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ , MetalLB๋กœ ์˜จํ”„๋ ˆ๋ฏธ์Šค LoadBalancer๋ฅผ ๊ตฌ์„ฑํ•˜๋ฉฐ, App-of-Apps ํŒจํ„ด์œผ๋กœ ์ „์ฒด ํ”Œ๋žซํผ์„ ์„ ์–ธ์ ์œผ๋กœ ๋™๊ธฐํ™”ํ•˜๋Š” GitOps ๊ณ ๋„ํ™” ๊ณผ์ •์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ์„ ์ˆ˜์ง€์‹ MLOps ์šด์˜ ๊ณ ๋„ํ™” 5๋‹จ๊ณ„: Airflow ์•ˆ์ •ํ™” & FastAPI HTTPS โ€” TLS ๋ณด์•ˆ๊ณผ ์Šค์ผ€์ค„๋Ÿฌ ์•ˆ์ •ํ™” ์ด ๋‹จ๊ณ„์—์„œ ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๋ฌธ์ œ ํ™˜๊ฒฝ(dev/prod)์ด ๋Š˜์–ด๋‚ ์ˆ˜๋ก ArgoCD Application YAML์ด ์ค‘๋ณต๋˜๊ณ , ํ™˜๊ฒฝ ๊ฐ„ ์„ค์ • ๋“œ๋ฆฌํ”„ํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์˜จํ”„๋ ˆ๋ฏธ์Šค ํ™˜๊ฒฝ์—์„œ๋Š” ํด๋ผ์šฐ๋“œ ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๊ฐ€ ์—†์–ด ์™ธ๋ถ€ ์ ‘๊ทผ์ด ์–ด๋ ต๋‹ค. ๊ฐœ๋ณ„ Application์„ ์ˆ˜๋™์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด ์ „์ฒด ํ”Œ๋žซํผ ์ƒํƒœ๋ฅผ ํ•œ๋ˆˆ์— ํŒŒ์•…ํ•˜๊ธฐ ํž˜๋“ค๋‹ค. ...

August 27, 2025 ยท 3 min

[MLOps ์šด์˜ ๊ณ ๋„ํ™” - 5๋‹จ๊ณ„: Airflow ์•ˆ์ •ํ™” & FastAPI HTTPS ๋ณด์•ˆ]

์ด ๊ธ€์—์„œ ๋‹ค๋ฃจ๋Š” ๊ฒƒ Airflow Sensor๋ฅผ reschedule ๋ชจ๋“œ๋กœ ๋ฆฌํŒฉํ† ๋งํ•˜๊ณ  ์„ฑ๊ณต ์ฒด์ธ์„ ๋ณด์žฅํ•˜๋Š” DAG ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค๊ณ , FastAPI์— cert-manager ๊ธฐ๋ฐ˜ TLS + IP ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ๋ฅผ ์ ์šฉํ•˜๋Š” ๊ณผ์ •์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ์„ ์ˆ˜์ง€์‹ MLOps ์šด์˜ ๊ณ ๋„ํ™” 7๋‹จ๊ณ„: ArgoCD Notifications ์ž๋™ํ™” โ€” ๋ฐฐํฌ ์ƒํƒœ Slack ์ž๋™ ์•Œ๋ฆผ ์ด ๋‹จ๊ณ„์—์„œ ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๋ฌธ์ œ ๋ชจ๋ธ์„ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ์ค‘์š”ํ•œ ๊ฑด ์–ธ์ œ Reload๊ฐ€ ์‹คํ–‰๋˜๋А๋ƒ์ด๋‹ค. ๋“ฑ๋ก ์‹คํŒจ๋‚˜ READY ๋ฏธ๋„๋‹ฌ ์ƒํƒœ์—์„œ /reload๊ฐ€ ์‹คํ–‰๋˜๋ฉด ์ž˜๋ชป๋œ ๋ชจ๋ธ์ด ์„œ๋น™๋  ์ˆ˜ ์žˆ๋‹ค. Airflow ํ๋ฆ„์„ ํ•œ ๋ฒˆ ๋” ๋‹จ๋‹จํžˆ ์กฐ์ด๊ณ , FastAPI ์ชฝ์€ HTTPSยทํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ๊นŒ์ง€ ์ ์šฉํ•ด ์•ˆ์ „ํ•˜๊ฒŒ ์ž๋™ํ™”๋œ๋‹ค๋Š” ํ™•์‹ ์„ ์ฃผ๋Š” ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ ๋‹ค. ...

August 18, 2025 ยท 4 min

[MLOps ์šด์˜ ๊ณ ๋„ํ™” - 4๋‹จ๊ณ„: FastAPI ๋กœ๊ทธ ์•ˆ์ •ํ™” (NFS + PV/PVC + Loguru)]

์ด ๊ธ€์—์„œ ๋‹ค๋ฃจ๋Š” ๊ฒƒ Pod ์žฌ์‹œ์ž‘ ์‹œ ๋กœ๊ทธ๊ฐ€ ์œ ์‹ค๋˜์ง€ ์•Š๋„๋ก NFS ๊ธฐ๋ฐ˜ PV/PVC๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ , Loguru๋กœ ๊ตฌ์กฐํ™”๋œ ํŒŒ์ผ ๋กœ๊น…์„ ์ ์šฉํ•˜์—ฌ FastAPI ์„œ๋น™ ๋กœ๊ทธ๋ฅผ ์˜์†ํ™”ํ•˜๋Š” ๊ณผ์ •์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ์„ ์ˆ˜์ง€์‹ MLOps ์šด์˜ ๊ณ ๋„ํ™” 3๋‹จ๊ณ„: ๋ชจ๋ธ ๋กค๋ฐฑ ์ž๋™ํ™” โ€” ์Šค๋ƒ…์ƒท ๊ธฐ๋ฐ˜ ์ž๋™ ๋กค๋ฐฑ ์ด ๋‹จ๊ณ„์—์„œ ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๋ฌธ์ œ FastAPI Pod๊ฐ€ ์žฌ์‹œ์ž‘๋˜๊ฑฐ๋‚˜ ์Šค์ผ€์ผ ๋‹ค์šด๋˜๋ฉด ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์— ์Œ“์ธ ๋กœ๊ทธ๊ฐ€ ๋ชจ๋‘ ์‚ฌ๋ผ์ง„๋‹ค. ํ•ซ์Šค์™‘ ์ด๋ ฅ, ์˜ˆ์ธก ์š”์ฒญ ๊ธฐ๋ก, ์—๋Ÿฌ ํŠธ๋ ˆ์ด์Šค๊ฐ€ ์œ ์‹ค๋˜๋ฉด ์žฅ์•  ์›์ธ์„ ์ถ”์ ํ•  ์ˆ˜ ์—†๋‹ค. Pod ๋ผ์ดํ”„์‚ฌ์ดํด๊ณผ ๋…๋ฆฝ์ ์œผ๋กœ ๋กœ๊ทธ๋ฅผ ๋ณด์กดํ•˜๋Š” ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ...

August 8, 2025 ยท 3 min

[MLOps ์šด์˜ ๊ณ ๋„ํ™” - 3๋‹จ๊ณ„: ๋ชจ๋ธ ๋กค๋ฐฑ ์ž๋™ํ™” (๋“ฑ๋ก ์‹คํŒจ ๋Œ€๋น„ ๋ณต๊ตฌ)]

์ด ๊ธ€์—์„œ ๋‹ค๋ฃจ๋Š” ๊ฒƒ ๋ชจ๋ธ ๋“ฑ๋ก ์‹คํŒจ ์‹œ ์ด์ „ ์•ˆ์ • ๋ฒ„์ „์œผ๋กœ ์ž๋™ ๋กค๋ฐฑํ•˜๊ณ  FastAPI์— ์ฆ‰์‹œ ๋ฐ˜์˜ํ•˜๋Š” ๋ณต๊ตฌ ๋ฃจํ”„์™€, ์šด์˜์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ๋ฒ„์ „์„ ์ง€์ •ํ•˜๋Š” ์ˆ˜๋™ ๋กค๋ฐฑ DAG์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ณผ์ •์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ์„ ์ˆ˜์ง€์‹ MLOps ์šด์˜ ๊ณ ๋„ํ™” 2๋‹จ๊ณ„: Slack Alert ํ†ตํ•ฉ โ€” ํŒŒ์ดํ”„๋ผ์ธ ์•Œ๋ฆผ ์ž๋™ํ™” ์ด ๋‹จ๊ณ„์—์„œ ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๋ฌธ์ œ ๋ชจ๋ธ ๋ฐฐํฌ๋Š” ์„ฑ๊ณตํ–ˆ์„ ๋•Œ๋ณด๋‹ค, ์‹คํŒจํ–ˆ์„ ๋•Œ์˜ ํšŒ๋ณต ์†๋„๊ฐ€ ์šด์˜ ํ’ˆ์งˆ์„ ๊ฒฐ์ •ํ•œ๋‹ค. ๋“ฑ๋ก์ด ์‹คํŒจํ•˜๋Š” ์ฆ‰์‹œ ์ด์ „ ์•ˆ์ • ๋ฒ„์ „์œผ๋กœ ๋Œ์•„๊ฐ€ FastAPI์— ์ž๋™ ๋ฐ˜์˜๋˜๋Š” ์™„์ „ํ•œ ๋กค๋ฐฑ ๋ฃจํ”„๋ฅผ ๊ตฌ์ถ•ํ•ด์•ผ ํ•œ๋‹ค. ์ด ๊ตฌ์กฐ๊ฐ€ ์žˆ์–ด์•ผ ์žฅ์•  ์ƒํ™ฉ์—์„œ๋„ ์„œ๋น„์Šค๊ฐ€ ๋Š๊ธฐ์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ๋ณต๊ตฌ๋  ์ˆ˜ ์žˆ๋‹ค. ...

August 1, 2025 ยท 4 min

[MLOps ์šด์˜ ๊ณ ๋„ํ™” - 2๋‹จ๊ณ„: Slack Alert ํ†ตํ•ฉ (FastAPIยทAirflow ๊ณต์šฉ)]

์ด ๊ธ€์—์„œ ๋‹ค๋ฃจ๋Š” ๊ฒƒ FastAPI์™€ Airflow๊ฐ€ ํฉ์–ด์ ธ ๋ณด๋‚ด๋˜ ์•Œ๋ฆผ์„ ํ•˜๋‚˜์˜ Slack ์ธํ„ฐํŽ˜์ด์Šค๋กœ ํ†ตํ•ฉํ•˜๊ณ , SealedSecret ๊ธฐ๋ฐ˜์œผ๋กœ Webhook URL์„ ์•ˆ์ „ํ•˜๊ฒŒ ์ฃผ์ž…ํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ์„ ์ˆ˜์ง€์‹ MLOps ์šด์˜ ๊ณ ๋„ํ™” 1๋‹จ๊ณ„: ํ•ซ์Šค์™‘ ๊ณ ๋„ํ™” โ€” /reload ๋ณด์•ˆ ๊ฐ•ํ™”์™€ DAG ์ž๋™ํ™” ์ด ๋‹จ๊ณ„์—์„œ ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๋ฌธ์ œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ ๊ฐ€์žฅ ๋ฌด์„œ์šด ๊ฑด ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋Š”๋ฐ ์•„๋ฌด๋„ ๋ชจ๋ฅด๊ณ  ์žˆ๋Š” ์ƒํ™ฉ์ด๋‹ค. FastAPI์™€ Airflow๊ฐ€ ๊ฐ์ž ํฉ์–ด์ ธ ๋ณด๋‚ด๋˜ ์•Œ๋ฆผ์„ ํ•˜๋‚˜์˜ Slack ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์™„์ „ํžˆ ํ†ตํ•ฉํ•ด์„œ, ๋ชจ๋ธ ํ•™์Šตยท๋“ฑ๋กยท์„ผ์„œยทํ•ซ์Šค์™‘ยทํ—ฌ์Šค์ฒดํฌ๊นŒ์ง€ ์–ด๋””์—์„œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๋„ ์ฆ‰์‹œ ๋ˆˆ์— ๋“ค์–ด์˜ค๋„๋ก ๋งŒ๋“ ๋‹ค. ...

July 26, 2025 ยท 4 min

[MLOps ์šด์˜ ๊ณ ๋„ํ™” - 1๋‹จ๊ณ„: ํ•ซ์Šค์™‘ ๊ณ ๋„ํ™” (/reload ๋ณด์•ˆยทDAG ์ž๋™ํ™”)]

์ด ๊ธ€์—์„œ ๋‹ค๋ฃจ๋Š” ๊ฒƒ /reload ์—”๋“œํฌ์ธํŠธ์— 3์ค‘ ๋ณด์•ˆ(ํ† ํฐยทIP ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธยทTLS)์„ ์ ์šฉํ•˜๊ณ , Airflow DAG์œผ๋กœ ํ•™์Šตโ†’๋“ฑ๋กโ†’๊ฐ์‹œโ†’ํ•ซ์Šค์™‘ ์ „์ฒด ์‹œํ€€์Šค๋ฅผ ์ž๋™ํ™”ํ•˜๋Š” ๊ณผ์ •์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ์„ ์ˆ˜์ง€์‹ MLOps ์šด์˜ ๊ณ ๋„ํ™” 0๋‹จ๊ณ„: FastAPI A/BยทCanaryยทBlue-Green ์„œ๋น™ ๋ฒ ์ด์Šค โ€” ๋ฉ€ํ‹ฐ ๋ชจ๋ธ ๋ผ์šฐํŒ… ๊ธฐ๋ฐ˜ ์„ค๊ณ„ ์ด ๋‹จ๊ณ„์—์„œ ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๋ฌธ์ œ ๋ชจ๋ธ์„ ์ž˜ ํ•™์Šต์‹œํ‚ค๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•˜์ง€๋งŒ, ์ž˜๋ชป๋œ ๋ชจ๋ธ์ด ์‹ค์ˆ˜๋กœ ํ•ซ์Šค์™‘๋˜๋Š” ์ˆœ๊ฐ„์ด ๋” ์น˜๋ช…์ ์ด๋‹ค. /reload๋ฅผ ํ™•์‹คํ•˜๊ฒŒ ์ž ๊ทธ๊ณ , ํ•™์Šตโ†’๋“ฑ๋กโ†’๊ฐ์‹œโ†’ํ•ซ์Šค์™‘๊นŒ์ง€๊ฐ€ Airflow์—์„œ ์ž๋™์œผ๋กœ ํ˜๋Ÿฌ๊ฐ€๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ์ด ๋‹จ๊ณ„๊ฐ€ ์™„์„ฑ๋ผ์•ผ ์ดํ›„ ๋‹จ๊ณ„์—์„œ ์•ˆ์ „ํ•œ ์ž๋™ ์šด์˜(MLOps)์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ...

July 22, 2025 ยท 4 min

[MLOps ์šด์˜ ๊ณ ๋„ํ™” - 0๋‹จ๊ณ„: FastAPI A/BยทCanaryยทBlue-Green ์„œ๋น™ ๋ฒ ์ด์Šค]

์ด ๊ธ€์—์„œ ๋‹ค๋ฃจ๋Š” ๊ฒƒ MLflow Alias ๊ธฐ๋ฐ˜์œผ๋กœ A/BยทCanaryยทBlue-Green ์„ธ ๊ฐ€์ง€ ์„œ๋น™ ์ „๋žต์„ ํ•˜๋‚˜์˜ FastAPI ์•ฑ์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ์„ค๊ณ„ํ•˜๊ณ , ์ดํ›„ ์šด์˜ ์ž๋™ํ™”์˜ ๊ณตํ†ต ๋ฒ ์ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ •์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ์„ ์ˆ˜์ง€์‹ [TS] Airflow ๊ธฐ์ดˆ ์ž๋™ํ™” ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… โ€” Airflow โ†’ MLflow โ†’ FastAPI ์—ฐ๋™ ๊ธฐ๋ณธ ํ๋ฆ„ Level 3์€ ์ด ๊ธ€๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„์—์„œ ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๋ฌธ์ œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ ๋ชจ๋ธ์€ ์–ธ์ œ๋“  ๊ต์ฒด๋  ์ˆ˜ ์žˆ๊ณ , ๊ทธ ์ˆœ๊ฐ„์ด ์„œ๋น„์Šค ํ’ˆ์งˆ์ด ๊ฐ€์žฅ ํฌ๊ฒŒ ํ”๋“ค๋ฆฌ๋Š” ์œ„ํ—˜ ๊ตฌ๊ฐ„์ด๋‹ค. ์ดํ›„ ๋ชจ๋“  ์ž๋™ํ™”(ํ•™์Šตยท๋“ฑ๋กยทํ•ซ์Šค์™‘ยท๋กค๋ฐฑ)์˜ ๊ธฐ๋ฐ˜์ด ๋˜๋Š” A/BยทCanaryยทBlue-Green ์ „๋žต์„ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” FastAPI ์„œ๋น™ ๊ตฌ์กฐ๋ถ€ํ„ฐ ์žก์•„์•ผ ํ•œ๋‹ค. ์ด ๋ผˆ๋Œ€๊ฐ€ ์™„์„ฑ๋ผ์•ผ Airflow, MLflow, ArgoCD์™€ ์—ฐ๊ฒฐ๋œ ์šด์˜ํ˜• MLOps ํŒŒ์ดํ”„๋ผ์ธ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ...

July 18, 2025 ยท 5 min

[MLOps ํ”Œ๋žซํผ ๊ตฌ์ถ• : Airflow-MLflow-FastAPI (Helm)]

๐Ÿงฉ ์‹ค์ „ ์‹œ๋‚˜๋ฆฌ์˜ค ๊ธฐ๋ฐ˜ ๊ตฌ์„ฑ ๋ฐฐ๊ฒฝ ์ด ํ”„๋กœ์ ํŠธ๋Š” ๋‹จ์ˆœ ์‹ค์Šต์„ ๋„˜์–ด์„œ, ์‹ค์ œ ๋ฐœ์ƒํ•˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ MLOps ์ธํ”„๋ผ ๊ตฌ์ถ•์„ ๋ชฉํ‘œ๋กœ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๋ชจ๋ธ ์‹คํ—˜ ๊ฒฐ๊ณผ๊ฐ€ ๋’ค์„ž์—ฌ ์ถ”์ ์ด ์–ด๋ ค์šด ๋ฌธ์ œ โ†’ MLflow Tracking ์„œ๋ฒ„ + PostgreSQL ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ ๊ตฌ์„ฑ ๋ชจ๋ธ ํŒŒ์ผ ๋ฐ ๋กœ๊ทธ๊ฐ€ ๋กœ์ปฌ์—๋งŒ ์ €์žฅ๋˜์–ด ํ˜‘์—… ๋ฐ ์žฌํ˜„์„ฑ์ด ๋–จ์–ด์ง€๋Š” ๋ฌธ์ œ โ†’ S3 ๊ธฐ๋ฐ˜ artifact store ๊ตฌ์„ฑ + pyfunc ๊ธฐ๋ฐ˜ ๋ชจ๋ธ ์„œ๋น™ ๊ตฌ์กฐ ์„ค๊ณ„ ์ˆ˜์ž‘์—… DAG ๋“ฑ๋ก, ๋ชจ๋ธ ๋ฐฐํฌ ๋“ฑ์˜ ๋น„ํšจ์œจ์  ์šด์˜ ๋ฌธ์ œ โ†’ Airflow + GitSync ์—ฐ๋™์œผ๋กœ ํŒŒ์ดํ”„๋ผ์ธ ์ž๋™ํ™” ๋ฐ ๋ฒ„์ „ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ ...

July 15, 2025 ยท 3 min

[MLOps ํ”Œ๋žซํผ ๊ตฌ์ถ• - 6๋‹จ๊ณ„: ์‹ค์‹œ๊ฐ„ ๋ชจ๋ธ ํ•ซ์Šค์™‘ ๊ตฌ์กฐ ์‹คํ—˜]

์ด ๊ธ€์—์„œ ๋‹ค๋ฃจ๋Š” ๊ฒƒ Airflow DAG์—์„œ ์กฐ๊ฑด๋ถ€ ๋ชจ๋ธ ๋“ฑ๋ก ํ›„ FastAPI ํ•ซ์Šค์™‘๊นŒ์ง€ E2E ์ž๋™ํ™” ํ๋ฆ„์„ ์‹คํ—˜ํ•ฉ๋‹ˆ๋‹ค. ์„ ์ˆ˜์ง€์‹ MLOps ํ”Œ๋žซํผ ๊ตฌ์ถ• 5๋‹จ๊ณ„: FastAPI ์„œ๋น™ ๋ฐ ํ•ซ์Šค์™‘ ๊ตฌ์กฐ ๊ตฌ์ถ• โ€” FastAPI ๋ชจ๋ธ ๋กœ๋”ฉ๊ณผ /reload API ๊ตฌ์กฐ ์ด ๋‹จ๊ณ„์—์„œ ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๋ฌธ์ œ ๊ฐœ๋ณ„ ์ปดํฌ๋„ŒํŠธ(Airflow, MLflow, FastAPI)๋ฅผ ๊ฐ๊ฐ ๊ตฌ์„ฑํ–ˆ์ง€๋งŒ, ํ•™์Šต๋ถ€ํ„ฐ ์„œ๋น™๊นŒ์ง€์˜ ์ž๋™ํ™” ํ๋ฆ„์„ E2E๋กœ ๊ฒ€์ฆํ•ด์•ผ ์‹ค์ œ ์šด์˜ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„์—์„œ๋Š” Airflow DAG์—์„œ ๋ชจ๋ธ ํ•™์Šต โ†’ ์„ฑ๋Šฅ ๊ธฐ์ค€ ๋ถ„๊ธฐ โ†’ MLflow ๋“ฑ๋ก โ†’ FastAPI ํ•ซ์Šค์™‘๊นŒ์ง€ ์ „์ฒด ํŒŒ์ดํ”„๋ผ์ธ์„ ์‹คํ—˜ํ•ฉ๋‹ˆ๋‹ค. ...

July 10, 2025 ยท 2 min

[MLOps ํ”Œ๋žซํผ ๊ตฌ์ถ• - 5๋‹จ๊ณ„: FastAPI ์„œ๋น™: MLflow ๋ชจ๋ธ ์—ฐ๋™ ๋ฐ ํ•ซ์Šค์™‘ ๊ตฌ์กฐ ๊ตฌ์ถ•]

์ด ๊ธ€์—์„œ ๋‹ค๋ฃจ๋Š” ๊ฒƒ MLflow์— ๋“ฑ๋ก๋œ ๋ชจ๋ธ์„ FastAPI๋กœ ์„œ๋น™ํ•˜๊ณ , Stage ๊ธฐ๋ฐ˜ ํ•ซ์Šค์™‘๊ณผ ๋ชจ๋ธ ์ •๋ณด ์กฐํšŒ API๋ฅผ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค. ์„ ์ˆ˜์ง€์‹ MLOps ํ”Œ๋žซํผ ๊ตฌ์ถ• 4๋‹จ๊ณ„: Airflow GitSync + Secret ์—ฐ๋™ โ€” Helm ๋ฐฐํฌ์™€ Secret ๋งˆ์šดํŠธ ํŒจํ„ด ์ด ๋‹จ๊ณ„์—์„œ ํ•ด๊ฒฐํ•˜๋ ค๋Š” ๋ฌธ์ œ ๋ชจ๋ธ์„ ์ˆ˜๋™์œผ๋กœ ์„œ๋น™ ์„œ๋ฒ„์— ๋ณต์‚ฌํ•˜๋ฉด ๋ฐฐํฌ ์‹ค์ˆ˜์™€ ๋ฒ„์ „ ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. MLflow Registry์—์„œ Stage๋ณ„ ๋ชจ๋ธ์„ ์ž๋™ ๋กœ๋”ฉํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค์–ด, ์ฝ”๋“œ ๋ณ€๊ฒฝ ์—†์ด ๋ชจ๋ธ์„ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ“ ์•„ํ‚คํ…์ฒ˜ ๊ตฌ์„ฑ๋„ ๐Ÿณ FastAPI ์ปค์Šคํ…€ ์ด๋ฏธ์ง€ Dockerfile FROM python:3.12 WORKDIR /app COPY app /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] requirements.txt fastapi==0.110.2 uvicorn==0.29.0 mlflow==2.13.0 pandas==2.1.4 scikit-learn==1.6.1 pydantic==2.7.1 boto3==1.34.113 numpy==1.26.4 packaging==24.2 psutil==7.0.0 scipy==1.15.3 setuptools==69.5.1 ๋นŒ๋“œ & ํ‘ธ์‹œ docker build -t ghcr.io/hoizz/fastapi-ml:mlflow-model-info . docker push ghcr.io/hoizz/fastapi-ml:mlflow-model-info ๐Ÿ“„ app/main.py (ํ•ต์‹ฌ ๋ถ€๋ถ„) app = FastAPI() model = None model_info = {} def load_model_from_mlflow(): global model, model_info tracking_uri = os.environ.get("MLFLOW_TRACKING_URI") model_name = os.environ.get("MODEL_NAME") model_stage = os.environ.get("MODEL_STAGE", "Production") mlflow.set_tracking_uri(tracking_uri) model_uri = f"models:/{model_name}/{model_stage}" model = mlflow.pyfunc.load_model(model_uri) client = MlflowClient() latest = client.get_latest_versions(name=model_name, stages=[model_stage])[0] model_info = { "model_name": model_name, "stage": model_stage, "version": latest.version, "run_id": latest.run_id, "model_uri": model_uri, } @app.on_event("startup") def startup_event(): load_model_from_mlflow() @app.get("/model-info") def get_model_info(): return model_info @app.post("/predict") async def predict(request: Request): input_data = await request.json() prediction = model.predict(input_data) return {"prediction": prediction.tolist()} ์ „์ฒด ์ฝ”๋“œ: GitHub (main.py) ...

July 7, 2025 ยท 2 min