LLMOps 02

LLMOps, 왜 그렇게 다른가?

Ops라는 이름이 비슷해서 DevOps, MLOps, LLMOps가 같은 자동화 도구처럼 보인다.

근거 · 교안 p8-p9

LLMOps, 왜 그렇게 다른가? 대표 이미지

1장: Ops가 모두 같은 건 아니야: DevOps와 MLOps의 탄생

솔라는 거실 소파에 앉아 노트북 화면을 멍하니 바라보고 있었다. 화면 한구석에는 ‘DevOps와 MLOps에서 LLMOps로’라는 제목의 기술 블로그 탭이 열려 있었다. 방금 전까지 흥미롭게 읽던 글이었지만, 한 문장에 턱 막혀버렸다.

“DevOps는 개발과 운영 통합, MLOps는 모델 생애주기 관리…”

분명 아는 단어들의 조합이었다. 하지만 솔라의 머릿속에서는 세 개의 ‘Ops’가 뒤섞여 희미한 안개처럼 흩어질 뿐이었다. 잠시 후, 주방에서 커피를 들고나오던 언니 루나가 솔라의 굳은 표정을 발견했다.

“뭘 그렇게 심각하게 보고 있어?”

“아, 언니. 마침 잘 됐다. 나 지금 머리에 안개가 낀 것 같아.”

솔라는 노트북을 루나 쪽으로 돌렸다.

“이것 좀 봐. DevOps, MLOps, LLMOps. 이름에 다 ‘Ops’가 붙으니까, 그냥 다 비슷한 자동화 도구 같은 거 아니야? 결국 개발이나 운영을 편하게 하려는 거잖아. 그런데 굳이 왜 이렇게 나눠서 부르는 걸까? 그냥 이름만 바꾼 새로운 유행인가 싶기도 하고.”

솔라의 말에는 ‘비슷한 이름이니 기능도 비슷할 것’이라는 확신이 섞여 있었다. 그럴듯한 추측이었다. 루나는 커피 잔을 내려놓고 소파에 앉으며 고개를 끄덕였다.

“그렇게 생각할 수 있지. ‘Ops’라는 이름이 주는 인상이 있으니까. 그런데 솔라, 그 단어들이 해결하려던 ‘문제’를 상상해 본 적 있어? 도구가 아니라, 그 도구가 필요했던 상황 말이야.”

“상황?”

“응. 각 ‘Ops’가 등장했을 때, 그 앞에는 거대한 벽이 하나씩 서 있었거든. 사람들은 그 벽 때문에 아주 불편해했지.”

루나는 손으로 허공에 네모난 벽을 그렸다.

“먼저 DevOps부터 생각해 보자. 한쪽에는 소프트웨어를 만드는 ‘개발팀’이 있고, 벽 너머 다른 쪽에는 그 소프트웨어를 실제 서버에서 돌리는 ‘운영팀’이 있어. 개발팀은 새 기능을 빨리 만들어서 사용자에게 보여주고 싶은데, 운영팀은 시스템이 안정적으로 돌아가는 게 더 중요해. 개발팀이 완성된 코드를 벽 너머로 휙 던지면, 운영팀은 그걸 받아서 설치하다가 문제가 생겨도 뭐가 문제인지 알기 어렵고. 그럼 서로 손가락질만 하게 되겠지. 어때?”

솔라는 눈을 감고 그 장면을 상상했다. 개발자들이 운영팀을 탓하고, 운영팀은 개발팀의 코드가 엉망이라고 불평하는 모습이 생생하게 그려졌다. 출시일은 계속 늦어지고, 사용자들의 불만은 쌓여갔다.

“정말 답답하겠다. 일은 일대로 하고 욕은 욕대로 먹고. 그럼 DevOps는 그 벽을 부수려고 나온 거구나.”

“바로 그거야. ‘개발(Dev)’과 ‘운영(Ops)’을 따로 떼어놓지 말고, 처음부터 같이 일하게 하자. 하나의 목표를 보고 달리게 하자. 그게 바로 DevOps의 핵심 아이디어, 즉 ‘통합’이었어. 벽을 허물어서 개발부터 배포, 운영까지의 흐름을 매끄럽게 만든 거지.”

솔라의 얼굴에 희미한 깨달음이 스쳤다. ‘Ops’는 그냥 ‘운영 자동화’가 아니라, 어떤 ‘분리된 구조’를 ‘통합’하려는 움직임이었다.

“좋아, 그럼 MLOps는?” 솔라가 물었다.

“같은 방식으로 생각해 봐. 이제 개발팀과 운영팀 옆에 새로운 팀이 생겼어. 머신러닝 ‘모델’을 만드는 팀이야.”

루나는 허공에 그린 벽 옆에 또 다른 벽을 세우는 시늉을 했다.

“이 팀은 아주 성능 좋은 모델을 만들었어. 그런데 이 모델은 그냥 코드 덩어리가 아니야. 특정 버전의 데이터로 학습했고, 특별한 라이브러리가 필요하고, 또 주기적으로 성능이 떨어지는지 감시해야 해. 이걸 예전처럼 개발팀에 그냥 휙 던져주면, 개발팀은 이걸 어떻게 자신들의 서비스에 넣어야 할지 막막하겠지. 운영팀은 말할 것도 없고. 또 다른 벽이 생긴 거야.”

솔라는 미간을 찌푸렸다. “아… 문제의 종류가 다르네. 그냥 코드가 아니라 ‘모델’이라는 게 끼어드니까. 데이터도 관리해야 하고, 학습 과정도 있어야 하고, 배포한 뒤에도 계속 지켜봐야 하고. 이건 개발과 운영만 합친다고 해결될 문제가 아니구나.”

“정확해. 그래서 MLOps가 필요해진 거야. 소프트웨어 개발 주기와는 또 다른, 이 ‘모델’만의 생애 주기를 시스템에 안전하게 ‘통합’하는 것. 데이터 준비, 모델 학습, 평가, 배포, 모니터링으로 이어지는 복잡한 과정을 관리하는 데 초점을 맞춘 거지.”

그제야 솔라는 아까 무심코 읽었던 문장을 다시 떠올렸다. ‘DevOps는 개발과 운영 통합, MLOps는 모델 생애주기 관리.’ 처음에는 그저 건조한 정의로 보였던 문장이, 이제는 각기 다른 시대의 고민과 해결책을 담은 압축 파일처럼 느껴졌다.

“알겠다! 이름이 비슷하다고 해서 같은 문제를 푸는 게 아니었어. 어떤 ‘분리된 구조’를 해결하려고 하는지, 그 ‘초점’을 봐야 했던 거네. DevOps는 개발팀과 운영팀 사이의 벽을, MLOps는 모델과 시스템 사이의 벽을 허물려고 했던 거구나.”

솔라는 자신이 방금 얻은 새로운 관점, ‘초점 분리 관점’을 이용해 상황을 명쾌하게 정리했다. 이제 더 이상 ‘Ops’라는 접미사에 휘둘리지 않을 것 같았다. 하지만 명쾌해진 만큼 새로운 궁금증이 고개를 들었다.

“잠깐만, 언니. 그럼 LLMOps는? LLM도 결국 머신러닝 모델이잖아. 그럼 MLOps로 관리하면 되는 거 아니야? MLOps가 모델 ‘학습’의 생애주기를 관리한다면서, 왜 LLMOps는 갑자기 ‘운영’에 집중한다고 하는 거지? 도대체 뭐가 그렇게 다른 건데?”

2장: 모델 학습에서 시스템 운영으로: MLOps와 LLMOps의 갈림길

다음 날 오후, 솔라는 거실의 화이트보드 앞에 서서 골똘히 생각에 잠겨 있었다. 어제 루나와 나눈 대화 이후, 그녀는 ‘초점 분리 관점’이라는 자신만의 무기를 얻었다. 그걸로 LLMOps의 정체까지 꿰뚫어 보려 했지만, 생각처럼 쉽지 않았다.

보드에는 두 개의 단정한 칸이 그려져 있었다. 왼쪽 ‘MLOps’ 칸에는 자신감 있는 글씨로 ‘데이터 준비 → 모델 학습 → 배포 → 모니터링’이라는 화살표가 이어져 있었다. 어제 배운 ‘모델 생애주기’를 깔끔하게 정리한 결과였다. 하지만 오른쪽 ‘LLMOps’ 칸은 엉망이었다. ‘LLM 학습?’이라고 썼다가 지운 흔적 위에, ‘프롬프트 관리?’, ‘체인?’, ‘비용?’ 같은 단어들이 물음표와 함께 흩어져 있을 뿐, 그 어떤 것도 명확한 흐름을 만들지 못했다. 마치 잘 닦인 MLOps의 고속도로 옆에, 이정표 없이 파편만 널린 비포장도로 같았다.

“이게 아닌데….”

솔라는 매직펜 뚜껑을 딱 소리 나게 닫으며 중얼거렸다. 뒤에서 지켜보던 루나가 조용히 다가왔다.

“뭐가 아니야?”

“아, 언니. MLOps는 ‘모델 생애주기’라는 확실한 초점이 있잖아. 그래서 LLMOps도 ‘LLM의 생애주기’라고 생각했는데, 그게 아닌 것 같아. 우린 보통 LLM을 직접 학습시키기보단 이미 만들어진 걸 가져다 쓰잖아. 그럼 ‘학습’ 단계가 빠지는데… 그럼 MLOps랑은 완전히 다른 이야기가 되어버리잖아. LLM도 머신러닝 모델인데, 왜 MLOps의 틀에 들어가지 않는 거지? 그냥 모델만 바뀐 단순한 확장이 아니었어?”

솔라의 질문에는 당혹감이 묻어났다. MLOps를 완벽하게 이해했다고 생각한 순간, LLM이라는 변수가 모든 걸 헝클어뜨린 것이다. 그녀는 LLMOps가 MLOps의 특별판 정도일 거라 여겼지만, 화이트보드의 빈칸은 그게 아니라고 말하고 있었다.

루나는 솔라의 화이트보드를 잠시 바라보더니, 고개를 끄덕였다.

“좋은 시도야. 같은 틀에 넣어서 비교해보려는 것. 그런데 그 틀이 맞지 않는다면, 틀 자체를 다시 생각해봐야 할 때인지도 몰라. 자, 이쪽으로 와봐.”

루나는 솔라를 다시 소파로 이끌었다. 그녀는 화이트보드의 ‘MLOps’나 ‘LLMOps’ 같은 딱지를 잠시 잊고, 완전히 새로운 상황을 상상해보자고 제안했다.

“우리가 ‘AI 여행 플래너 챗봇’을 만든다고 상상해 봐. 이 챗봇은 사용자가 ‘이번 주말에 부산으로 가는데, 재밌는 실내 활동이랑 맛집 좀 추천해 줘’라고 말하면, 그에 맞는 계획을 짜주는 거야.”

“오, 재밌겠다.”

“그런데 이 챗봇이 똑똑하게 대답하려면 몇 가지 일을 해야 해. 먼저, 실시간 날씨 정보를 확인해야 하고(API 호출), 최신 맛집 정보가 저장된 우리 데이터베이스를 검색해야 하지(DB 쿼리). 그리고 이 정보들을 종합해서, 마치 진짜 여행 전문가처럼 친절하고 자연스러운 문장으로 추천사를 만들어내야 해. 마지막 문장을 만드는 데 LLM을 쓰는 거지.”

루나의 설명에 솔라는 고개를 끄덕였다. 이제 루나는 솔라가 아까 정리했던 MLOps 파이프라인을 가리켰다.

“자, 그럼 이 ‘AI 여행 플래너’를 우리가 만든 MLOps 파이프라인으로 관리할 수 있을까? 어디에 빈틈이 생기는지 한번 상상해 봐.”

솔라는 눈을 감고 시뮬레이션을 시작했다.

‘첫째, 데이터 준비. 음… LLM을 직접 학습시키는 게 아니니까 대규모 데이터셋은 필요 없네. 하지만 사용자가 입력하는 ‘부산 여행 추천’ 같은 질문, 즉 ‘프롬프트’가 아주 중요하겠구나. 프롬프트가 조금만 달라져도 챗봇의 답변 품질이 완전히 달라질 테니까. MLOps의 데이터 준비랑은… 초점이 좀 다르네.’

‘둘째, 모델 학습. 이건 거의 해당 없네. 우린 이미 만들어진 LLM을 쓸 테니까.’

‘셋째, 배포 및 모니터링. 이건 해당되지. 모델이 죽었는지 살았는지 감시는 해야 하니까. 그런데… 만약 챗봇이 날씨 API를 너무 자주 호출해서 비용이 엄청나게 나오면 어떡하지? LLM이 환각을 일으켜서 있지도 않은 식당을 추천하면? MLOps의 모니터링은 보통 모델의 예측 정확도 같은 걸 보는데, 이건 그런 문제가 아니잖아. 이건… 이건 그냥 ‘운영’ 문제인데?’

생각을 마친 솔라가 눈을 떴다. 그녀의 얼굴에는 놀라움이 가득했다.

“알겠다! MLOps의 파이프라인은 더 좋은 ‘모델’을 만들고 유지하는 데 모든 초점이 맞춰져 있었어. 데이터도 모델 성능을 위해, 모니터링도 모델 성능을 위해. 그런데 방금 상상한 챗봇의 문제는 모델 자체의 성능 문제가 아니었어!”

솔라는 다시 화이트보드로 달려가 비어있던 ‘LLMOps’ 칸에 새로운 단어들을 적기 시작했다.

“사용자의 질문, 즉 프롬프트 관리. 날씨 API와 맛집 DB를 순서대로 호출하는 복잡한 체인의 흐름 제어. 그리고 API 호출마다 나가는 비용 관리. 이런 것들이 핵심 문제였던 거야. MLOps의 문제 공간이랑은 완전히 다른 문제들이네. 초점이 ‘모델 학습’에서 ‘시스템 운영’으로 완전히 옮겨갔어.”

마침내 솔라는 깨달았다. LLMOps는 MLOps의 확장판이 아니었다. 문제 공간 자체가 확장된, 완전히 새로운 영역이었다. 기존 MLOps가 다루던 ‘모델 생애주기’라는 지도에는 애초에 표시되지 않은 땅이었던 것이다.

솔라는 방금 자신이 얻은 ‘문제 공간 확장’이라는 새로운 관점으로 LLMOps를 바라보았다. 그러자 흩어져 있던 파편들이 하나의 그림으로 맞춰지기 시작했다. 하지만 그 그림은 또 다른 질문을 낳았다.

“그럼 언니, 이제 알겠어. LLMOps는 모델 학습이 아니라 이런 새로운 운영 문제들을 다루는 거구나. 그런데 아까부터 자꾸 ‘시스템’이라는 말을 쓰게 되네. 챗봇이라는 시스템, 흐름을 제어하는 시스템…. LLMOps가 LLM 기반 ‘시스템’을 통제한다는 게 정확히 무슨 말이지? 단순히 ‘모델’을 운영하는 거랑은 어떻게 다른 걸까?”

3장: LLM ‘모델’을 넘어 ‘시스템’을 통제하다: LLMOps의 본질

솔라의 시선은 화이트보드 한가운데에 새로 그린 커다란 사각형에 고정되어 있었다. ‘AI 여행 플래너 시스템’. 어제 흩어져 있던 ‘프롬프트’, ‘체인’, ‘비용’ 같은 단어들이 이제는 그 사각형 안에 들어와 있었다. 그리고 그 중심에는 유독 작은 동그라미 하나가 그려져 있었다. ‘LLM’. 솔라는 이 그림을 통해 어렴풋이 LLMOps가 MLOps와 다르다는 것은 알았지만, 마지막 한 걸음이 해결되지 않았다. 전체를 뜻하는 사각형과 부품을 뜻하는 동그라미. 둘의 관계가 명확하게 잡히지 않았다.

결국 그녀는 펜을 내려놓고 한숨을 쉬며 뒤를 돌아봤다. 마침 방에서 나오던 루나가 솔라의 고민 가득한 그림을 발견했다.

“어제 우리가 이야기한 걸 그려봤구나. 깔끔한데?”

“그런가? 난 더 혼란스러워졌는데. 봐봐, 언니. LLMOps가 다루는 문제들이 이 ‘시스템’이라는 큰 틀 안에 있다는 건 알겠어. 그런데 결국 이 시스템의 핵심은 이 ‘LLM’이라는 작은 동그라미, 즉 모델이잖아. 그럼 LLM이 똑똑하게 좋은 답변만 잘 생성하도록 만들면, 시스템 전체가 알아서 잘 돌아가는 거 아니야? 결국 모델 성능이 제일 중요한 거니까. ‘시스템을 통제한다’는 말이 너무 거창하게 들려. 그냥 ‘모델을 잘 운영한다’랑 뭐가 다른지 모르겠어.”

솔라의 말에는 ‘LLM 자체의 성능을 높이는 것이 LLMOps의 목표일 것’이라는 믿음이 깔려 있었다. 모델만 완벽하면 모든 게 해결될 것이라는, 엔지니어로서 가질 법한 자연스러운 가정이었다.

루나는 솔라의 그림을 잠시 들여다보더니, 미소와 함께 고개를 저었다.

“그 그림, 아주 중요한 포인트를 보여주고 있어. 솔라, 우리 이 시스템을 진짜 자동차처럼 다뤄볼까?”

루나는 테이블 위에 포스트잇 몇 장을 꺼내 부품의 이름을 적기 시작했다. ‘LLM 엔진’, ‘날씨 API’, ‘맛집 DB’, 그리고 ‘사용자 입력 핸들’. 루나는 포스트잇들을 테이블 위에 늘어놓고 그 사이를 펜으로 이어 하나의 흐름을 그렸다.

“자, 이게 우리 ‘AI 여행 플래너’ 자동차야. MLOps의 관점은 주로 이 ‘LLM 엔진’이라는 부품 자체에 집중해. 엔진의 출력이 얼마나 좋은지, 오작동은 없는지 같은 것들 말이야. 네가 말한 ‘모델 성능’이 바로 그거지.”

“맞아. 엔진이 좋아야 차가 잘 나가지.”

“물론이지. 그런데 우리는 지금 차를 ‘만드는’ 게 아니라, 이 차로 승객을 태우고 도로를 ‘운행’하는 상황이야.”

루나는 펜 끝으로 포스트잇 사이를 이은 화살표들을 톡톡 쳤다.

“만약 우리가 연결한 ‘날씨 API’가 갑자기 유료로 바뀌거나, 응답을 1초가 아니라 20초 만에 준다면 어떻게 될까? 우리 ‘LLM 엔진’은 아무런 문제가 없는데도, 차는 도로 한복판에 멈춰 서 있겠지.”

솔라는 미간을 찌푸렸다.

“또, 저쪽 ‘맛집 DB’ 부품이 고장 나서 엉뚱한 데이터를 주면? LLM 엔진은 그 데이터를 가지고 아주 그럴싸하고 유창하게, 하지만 완전히 틀린 ‘존재하지 않는 맛집’을 추천해 줄 거야. 엔진은 시키는 대로 했을 뿐인데, 승객은 우리 차가 엉터리라고 생각하게 돼.”

루나는 마지막으로 ‘사용자 입력 핸들’ 포스트잇을 가리켰다. “심지어 운전자, 즉 사용자가 이 차를 어떻게 다룰지도 문제야. 악의적인 사용자가 아주 길고 복잡한 목적지를 계속 입력해서 엔진을 과열시키면? 즉, LLM 토큰 사용량을 폭증시켜서 엄청난 비용이 발생하면? 이것 역시 엔진 자체의 성능 결함은 아니지.”

순간 솔라의 머릿속에서 뭔가 ‘쿵’ 하고 부딪히는 느낌이 들었다. 그녀의 시선은 더 이상 ‘LLM 엔진’이라는 포스트잇 하나에 머물지 않았다. 각 부품들을 잇는 화살표, 그리고 그 전체를 아우르는 보이지 않는 ‘운행’이라는 과정으로 확장되었다.

“아…! 이제야 알겠다. ‘모델 운영’은 이 LLM 엔진만 정비하고 튜닝하는 거였어. 하지만 ‘시스템 통제’는 엔진뿐만 아니라, 엔진에 연결된 외부 도로(API), 내비게이션(DB), 심지어 운전자의 습관(사용자 입력)까지 전부 고려해서, 이 자동차가 목적지까지 안전하고 효율적으로 ‘운행’되도록 관리하는 거였구나!”

솔라는 깨달았다. 모델 성능이 아무리 완벽해도, 부품과 부품을 잇는 연결 지점에서 문제가 터지면 시스템 전체가 망가질 수 있다는 것을. LLMOps의 진짜 문제 공간은 모델이라는 부품 자체가 아니었다. 부품들 사이의 상호작용과 전체 흐름에서 발생하는 예측 불가능성이었다.

“그러니까 LLMOps의 핵심은 ‘모델 성능’이 아니라, 이 연결부위에서 발생하는 통제, 비용, 안정성의 문제였던 거네.”

솔라는 자신이 얻은 새로운 ‘시스템 통제 관점’을 곧장 적용해 보고 싶었다. 그녀는 화이트보드로 달려가, 아까 그렸던 ‘AI 여행 플래너 시스템’ 그림을 지우기 시작했다. 그리고 자신이 요즘 구상하던 ‘코드 리뷰 자동화 봇’의 구조를 새로 그리기 시작했다.

중심에는 여전히 ‘LLM’이 있었다. 하지만 이제 그 주변에는 ‘GitHub API’, ‘정적 분석 도구’, ‘팀 코딩 컨벤션 DB’, ‘Slack 알림’ 같은 새로운 부품들이 그려졌다. 솔라는 단순히 네모와 화살표만 그리지 않았다. 붉은색 펜을 집어 들어, 각 부품을 잇는 화살표 위에 번개 모양(⚡)의 ‘위험 지점’ 표시를 하기 시작했다.

GitHub API 옆에는 ‘API 호출 수 제한(Rate Limit) 관리’. LLM 박스 옆에는 ‘토큰 사용량 모니터링 → 비용 통제’. Slack 알림으로 가는 화살표 위에는 ‘알림 실패 시 재시도 로직 & 포맷 안정성’.

그녀는 마침내 ‘팀 코딩 컨벤션 DB’와 LLM을 잇는 화살표 위에 마지막 번개 표시를 하며 적었다. ‘DB 변경 시, LLM 환각 현상 발생 가능성 통제’.

루나가 조용히 다가와 완성된 그림을 바라보았다. 단순한 기능 흐름도가 아니었다. 곳곳의 위험 요소를 식별하고 관리 포인트를 명시한, 살아있는 ‘시스템 통제 구조도’였다.

솔라는 펜을 내려놓고 자신의 그림을 바라보았다. 더 이상 ‘시스템’이라는 단어 앞에서 막막하지 않았다.

“이거였구나. LLMOps는 모델을 운영하는 것이 아니라, LLM 기반 시스템을 통제하는 것. 이제 이 문장이 진짜 내 것이 된 것 같아. 내가 관리해야 할 대상은 모델이 아니라, 바로 이 번개 표시들이었어.”