안녕하세요, 카카오뱅크 AI플랫폼팀의 ML 엔지니어 Toby입니다. 저는 사내에서 MLOps 문화가 효과적으로 정착하고 성장할 수 있도록 지원하며, 개발된 ML모델들을 카카오뱅크의 운영 서비스에 안정적으로 적용하는 업무를 주로 담당하고 있습니다.
이 글은 지난 1월 29일부터 한 달간 선보인 ‘나의 하루 응원받기 서비스’ 즉, 카카오뱅크 mini 일기 서비스의 개발 여정을 담고 있습니다. 해당 서비스는 AI를 활용해 mini 고객들이 일상에서 겪는 다양한 순간들을 감성적인 문장이 담긴 일기 형태로 전환해 주는 기능을 통해, 고객들이 그날의 기분을 선택하면 자신의 기분에 맞는 일기를 자동으로 생성해 주는데요. 이러한 기능은 mini 고객들에게 새로운 재미를 제공하고, 일상의 소소한 순간들을 기록하는 즐거움을 선사하는 것을 목표로 개발하게 되었습니다.
이때 카카오뱅크에서는 mini 일기 서비스 구축을 위해 Azure OpenAI의 기술을 활용했습니다. 이 글에서는 ChatGPT를 이용해 일기 생성 기능이 어떻게 구현되었는지, ChatGPT의 성능을 어떻게 분석했는지, 그리고 실제 서비스 적용 후 얻은 중요한 통찰들을 자세히 소개할 예정입니다. 글의 과정을 따라가면서, 여러분도 ChatGPT로 일기 서비스를 개발하는 경험을 간접적으로나마 해볼 수 있기를 바랍니다. 그럼, 지금 바로 시작해 볼까요?
mini 일기와 Azure OpenAI의 만남
1. 서비스 소개
mini 일기 서비스는 카카오뱅크에서 Azure OpenAI의 ChatGPT 기술을 대고객 운영 서비스에 적용해 본 첫 사례였다는 점이 개인적으로 굉장히 의미가 있었는데요. 그럼 본격적인 개발 이야기를 시작하기 전에, 잠시 mini 일기 서비스에 대해 사용 흐름을 중심으로 설명드리겠습니다.
- 먼저 mini 사용자가 ‘오늘의 mini 일기 서비스’에 입장하면,
매우 안 좋아요..
~매우 좋아요!
사이의 5가지 단계로 감정을 선택합니다. - 화면 하단에 위치한 ‘나의 하루 보기’ 버튼을 클릭하면, ChatGPT에게 mini 고객의 하루를 담은 일기 생성 요청이 보내집니다.
- 일기 생성을 위한 mini 고객의 체크카드 사용 정보가 익명화 되어 프롬프트 형태로 전달됩니다. 개인정보를 사용하지 않아 개인정보 유출의 위험을 원천적으로 방어 하였습니다.
- ChatGPT가 mini 고객의 하루 동안의 소소한 결제 내역들을 엮어, 하루를 돌아볼 수 있는 소비 일기를 생성합니다.
- 소비 일기 하단에 ‘AI가 알려준 내 감정 컬러는?’ 버튼을 누르면, 소비 일기를 바탕으로 오늘의 감정 컬러가 mini 고객에게 추가로 제공됩니다.
2. 프롬프트 요청/응답값
위의 흐름을 따라가다 보면, ‘ChatGPT에게 정확히 어떤 프롬프트가 전달되는 걸까?‘라는 의문을 가지는 분들이 계실 것 같아요. ChatGPT에 전달되는 프롬프트는 카카오뱅크의 금융기술연구소에서 엔지니어링 해주신 데이터를 기반으로 하는데요. 아래 요청값 예시를 프롬프트에 적용하여 ChatGPT에게 전달하면, 이를 기반으로 ChatGPT는 재미있는 일기를 생성하기 위한 소스를 얻게 됩니다.
{
"diary_concept": "10대",
"diary_transactions": [
["시간대", "카드가맹점이름", "카드가맹점위치", "업종분류"],
["오전", "GS25", "서울특별시 강남구", "체인편의점"],
["오전", "스타벅스", "서울특별시 서초구", "커피전문점"],
["오후", "차알 (chaR)", "서울특별시 서초구", "중식일반음식점"],
["오후", "요기요", "서울특별시 서초구", "배달앱"],
["오후", "교보문구 강남점", "서울특별시 서초구", "서점"]
]
}
요청값을 살펴보면, 크게 mini 고객의 오전/오후 체크카드 사용 내역이 녹아있는 것을 확인할 수 있는데요. 해당 정보를 프롬프트에 담아 전달했을 때, 아래의 응답값 예시처럼 ‘나의 소비생활을 그대로 담은 아기자기한 일기’가 만들어집니다. 이와 더불어 일기 내용과 감정을 색상 코드(HEX Triplet)로 표현하여 추가로 알려주기도 합니다.
(1) 소비 일기
오전에는 GS25에서 잠깐 들러서 간단한 먹거리를 사먹었어. 🍔 그리고 스타벅스에 가서 카페인을 충전했지! ☕️
오후에는 차알 (chaR)에서 중식을 먹었어. 🍜 그리고 배달앱인 요기요를 이용해서 맛있는 음식을 시켰어! 🍕
마지막으로 교보문구 강남점에 들러서 책을 구매했어. 📚
오늘은 쇼핑과 맛있는 음식을 즐기는 하루였어! 😄 다음에도 좋은 경험들로 가득한 하루를 보내고 싶어! 💪
(2) 오늘의 감정 컬러
#FFD700 (금색)
금융기술연구소의 시각에서 어떻게 프롬프트용 데이터를 엔지니어링 하였는지에 대한 이야기가 궁금하신 분들은 관련글을 참고해 주세요!
ChatGPT 일기 생성 기능 구현
ChatGPT를 사용하면서 mini 일기 서비스를 개발하는 것은 참 재미있고 흥미로웠습니다. 아래 [그림 2]는 mini 일기 생성 시작점부터 고객에게 전달되는 과정까지를 순서대로 워크플로우(Workflow) 형태로 나타낸 것입니다.
각 단계를 구체적으로 설명드리면 다음과 같습니다.
- 데이터 수집: 일기 생성에 필요한 데이터를 mini 고객이 당일 사용한 체크카드 거래 내역으로부터 수집합니다.
- 데이터 전처리: 체크카드 거래 내역에서 고객의 민감한 정보를 제거하고, 일기 생성에 필요한 핵심 정보만을 남깁니다.
- 프롬프트 생성: 전처리된 데이터를 이용하여 ChatGPT가 사용할 프롬프트를 생성합니다.
- ChatGPT 일기 생성: 생성된 프롬프트를 ChatGPT에 전달하여, 사용자를 위한 재미있는 일기를 생성합니다.
- 오늘의 일기 및 감정 전달: ChatGPT에 의해 생성된 일기와 감정을 최종적으로 mini 고객에게 전달합니다.
위와 같은 워크플로우를 설계하고 개발할 때 추가로 중요하게 고려했던 점은, 바로 ChatGPT가 일기를 생성할 때 발생할 수 있는 상당한 지연시간이었습니다. 이를 해결하기 위해 개발을 하며 ‘비동기식 논블록킹 방식’을 적극적으로 사용했는데요. 그 결과, 서비스 개발 과정에서 발생 가능한 이슈들을 면밀히 검토하여 기능을 구현했다고 자신할 수 있었습니다. 이러한 자신감을 바탕으로, 마침내 ChatGPT 기반의 mini 일기 서비스의 성능 테스트를 진행하였습니다.
그러나 성능 테스트 과정에서 ChatGPT의 예상치 못한 한계와 오류들을 경험하게 되었는데요. 뼈저린 교훈을 얻고는 ChatGPT의 활용과 개발에 대해 추가적인 통찰의 필요성과 발전 포인트를 고민하게 되었습니다. 무엇이 원인이었는지 다시 짚어보고, 어떻게 이 문제점을 해결해 나갔는지를 이어지는 글에서 설명드리겠습니다.
넘어야 할 산은 바로… TPM과 RPM 제한!
mini 일기 서비스 개발하면서 가장 큰 고민은 ‘서비스를 이용하는 고객 수가 증가하면, 동시에 얼마나 많은 사용자에게 일기를 생성해 줄 수 있을까?🧐’ 였습니다. 실제로 단일 사용자만 서비스를 이용한다면, 일기 생성 및 응답 프로세스는 상대적으로 간단할 수 있습니다. 그러나 여러 사용자가 동시에 mini 일기 생성을 요청하는 상황에서는, 특정 수준을 넘어서면 서비스가 폭주하는 요청량을 감당하기 어려워지는 상황에 직면하게 됩니다.
[그림 3]에서 확인할 수 있는 ‘mini 일기 서비스의 시스템 구성도’에서 대부분의 컴포넌트는 효율적으로 작동했습니다. 그런데 일기 생성 요청을 처리하는 ChatGPT 부분에서는 트래픽이 증가할 때 병목 현상이 발생했는데요. ChatGPT 서비스는 각 리전(Region)의 서버 스펙에 따라 설정되는 TPM(Tokens Per Minute, 분당 토큰 처리 수)과 RPM(Requests Per Minute, 분당 요청 수)을 가지고 있습니다. 각각 TPM과 RPM을 최대치에 도달하게 되면 제한이 걸리게 되는데, 이는 특히 사용량이 급증하는 시간대의 서비스 응답에 영향을 줄 수 있습니다.
일단 예상치 못하게 트래픽이 집중되는 상황이 발생하면, 위에서 언급한 리전별 TPM, RPM 제한들로 인해 밀려들어오는 사용자의 요청을 모두 처리하지 못하는 상황이 발생할 수 있습니다. 이는 서비스 지연이나 심각한 경우 서비스 중단으로까지 이어질 수 있으며, 사용자에게 불편을 줄 뿐만 아니라 결과적으로 서비스에 대한 불만과 이탈을 초래할 수 있는 중요한 문제입니다. 이러한 문제적인 상황을 해결하기 위해서는 서버 스펙과 트래픽 관리 전략의 확장성을 재검토할 필요가 있었습니다.
안정적인 서비스를 위한 ChatGPT 성능 분석
mini 일기 서비스를 고객에게 안정적으로 제공하기 위해, 저희는 ChatGPT 사용 프로세스를 보다 심도 있게 파악하기 시작했습니다. Azure에서 사용 가능한 ChatGPT 모델은 리전별 서버 스펙 차이로 인해 TPM과 RPM이 다릅니다. 이러한 차이는 서비스가 처리할 수 있는 RPS에 직접적인 영향을 미치는데요. 따라서 ChatGPT 모델의 TPM과 RPM 한도를 넘어서 요청했을 때 발생할 수 있는 문제점들을 직접 두 눈으로 확인하고자 팀에서는 ChatGPT 모델의 성능 분석을 진행하기로 결정했습니다.
우리는 꼭 경험을 해봐야 직성이 풀리는 개발자들이니까요 😉
다음과 같이 (1) ChatGPT 3.5의 0301 모델과 (2) ChatGPT 3.5의 0613 모델을 대상으로 성능 테스트를 진행하고 그 결과를 분석해 보았습니다. 이는 두 모델의 성능을 검증해 보는 동시에 두 모델 간의 차이점을 확인하여, 각 모델이 mini 일기 서비스에 적용되었을 때 ‘사용할 것으로 예상되는 토큰 수‘를 직접 계산 및 산출해 보기 위함이었습니다.
🔍 ChatGPT 3.5 0301 모델
(1) Request Statistics
구분 | # Requests | # Fails | Fails/Requests(%) | Average (ms) | Min (ms) | Max (ms) | RPS |
---|---|---|---|---|---|---|---|
1차 | 238,896 | 126 | 0.05 | 4,950 | 4,720 | 5,170 | 10.8 |
2차 | 244,188 | 357 | 0.15 | 6,660 | 5,560 | 7,570 | 18.0 |
3차 | 268,758 | 23,058 | 8.58 | 5,060 | 4,820 | 5,550 | 24.9 |
ChatGPT 3.5 0301 모델에서는 1차와 2차 성능 테스트를 진행하는 동안, Read Timeout와 같은 오류가 간헐적으로 발생했습니다. 그럼에도 대부분의 요청에 대해서는 응답을 받을 수 있었습니다. 참고로 Read Timeout 오류란, 클라이언트에서 설정한 시간까지 서버에서 응답이 오지 않았을 때 발생하는 오류로, 서로 연결은 되어 있지만 서버가 클라이언트의 요청을 정상적으로 처리하지 못했을 때 발생하는데요. 하지만 해당 오류가 간헐적으로 발생하는 원인은 다양할 수 있므로, 정확히 어떤 원인이 이를 유발했는지에 대해 상세한 원인 분석 보단 대응 방법을 찾는데 집중하기로 했습니다.
그렇게 Backoff 전략을 서비스에 도입하여 Read Timeout 상황에 대비하고자 했는데요. 3차 성능 테스트부터는 ChatGPT가 ‘사용자가 일정 시간 동안 너무 많은 요청을 보냈다’는 429 상태 코드(Too Many Requests, RFC 6585)를 응답으로 반환하기 시작했고, 에러율이 급격히 증가하는 추세를 보였습니다. 이를 통해 ChatGPT가 유량 제어를 사용하여 요청 처리에 제한을 두고 있음을 파악할 수 있었습니다.
(2) Failures Statistics
Error Type | Count |
---|---|
Read timed out. (read timeout=60) | 126 |
response.status_code == 429 | 22,932 |
위의 Failures Statistics 자료는 3차 성능 테스트 기준으로 작성되었는데요. 성능 테스트를 진행하는 동안 간헐적으로 발생한 Read Timeout 오류는, 확인 결과 대량의 트래픽이 몰리는 원인과는 별개였습니다. 또한 ChatGPT가 사용자의 요청을 처리하기 위한 처리량을 초과하면 Too Many Requests 오류(429)가 발생하는 것을 알 수 있었습니다.
🔍 ChatGPT 3.5 0613 모델
(1) Request Statistics
구분 | # Requests | # Fails | Fails/Requests(%) | Average (ms) | Min (ms) | Max (ms) | RPS |
---|---|---|---|---|---|---|---|
1차 | 238,865 | 11 | 0.00 | 7,940 | 7,400 | 9.060 | 18.1 |
2차 | 227,318 | 294 | 0.13 | 8,710 | 8,380 | 9,440 | 25.2 |
3차 | 228,480 | 4,578 | 2.00 | 8,630 | 8,140 | 9,030 | 28.5 |
ChatGPT 3.5 0613 모델은 앞서 소개한 0301 모델과 마찬가지로 3차 테스트부터 동일한 현상을 보였습니다. 그러나 2차 성능 테스트를 비교할 때, 0613 모델의 RPS(Requests per Second, 초당 요청 수)는 0301 모델보다 약 7.2만큼 더 높게 측정되었습니다. 이 결과는 우리가 보낸 요청에 대해 0613 모델이 같은 시간 내에 더 많은 요청을 처리할 수 있음을 의미하며, 이는 0613 모델의 처리 성능이 더 우수하다는 것을 확인할 수 있었습니다.
(2) Failures Statistics
Error Type | Count |
---|---|
response.status_code == 429 | 4,578 |
앞서 ChatGPT 3.5 0301 모델과 동일하게 요청 가능한 처리량을 초과하면, Too Many Requests 오류(429)가 발생하는 것을 확인했습니다.
📝 ChatGPT 성능 테스트 결론
ChatGPT 3.5의 두 모델(0301, 0613)의 성능 테스트를 진행하면서, 동일한 프롬프트를 사용했음에도 불구하고 모델마다 성능이 다름을 확인할 수 있었습니다. 특히 응답 처리 속도 면에서는 0301 모델의 평균 서비스 가능 RPS가 18.0이었으며, 이는 0613 모델의 25.2 RPS보다 낮았습니다. 이러한 RPS 차이는 일기 생성의 결과에 사용된 처리 토큰 수를 기준으로 측정되었습니다.
그런데 생성된 일기의 품질 면에서는 0301 모델이 더 우수한 성능을 보였습니다. 빠른 일기 생성 속도보다는 결과물의 품질을 높이는 것이 ChatGPT로 생성된 일기를 경험하는 고객의 만족도를 높일 것이라 판단했습니다. 따라서, 우수한 품질을 보여준 0301 모델을 선택하는 것이 더 합리적인 결정이었습니다. 이에 따라 mini 일기 서비스에는 ChatGPT 3.5 0301 모델을 채택하기로 결정했으며, 본격적인 작업에 앞서 0301 모델을 사용하는 여러 리전을 확보하여 최종 성능 테스트를 진행했습니다.
다수의 리전을 활용한 최종 성능 테스트
ChatGPT 3.5 0301 모델로 추가적으로 4개의 리전을 할당받았으며, 일기 생성 요청을 5개의 리전으로 분산 처리할 수 있도록 개발을 진행했습니다. 그렇게 0301 모델을 사용하는 5개의 리전으로 구성하고, mini 일기 서비스의 최종 성능 테스트를 수행하였습니다.
ChatGPT 3.5 0301 모델 (w/ 5 리전)
구분 | # Requests | # Fails | Fails/Requests(%) | Average (ms) | Min (ms) | Max (ms) | RPS |
---|---|---|---|---|---|---|---|
1차 | 228,261 | 44 | 0.02 | 7,780 | 4,950 | 9,480 | 87.7 |
2차 | 221,808 | 498 | 0.22 | 7,320 | 7,950 | 7,680 | 97.2 |
3차 | 224,028 | 3,132 | 1.40 | 8,090 | 7,730 | 8,690 | 104.4 |
성능 테스트 결과, 1~3회 모두 Read Timeout 오류는 동일하게 발생했지만, 오로지 3차 성능 테스트에서만 429 응답 코드가 발생하면서 오류율이 급격하게 상승했습니다. 그 이유는 앞서 살펴본 ChatGPT 성능 분석과 같이 다량의 요청이 ChatGPT에게 전달되어 요청가능한 처리량이 초과하였고, 429 상태 코드가 응답되었기 때문입니다. 이에 따라, 2차 성능 테스트 결과인 97.2 RPS를 서비스 가능한 수준으로 간주하고, 이를 기반으로 Backoff 전략을 적용했습니다.
스트레스 테스트 및 최종 점검
앞서 설명드린 최종 성능 테스트 이후에도, 보다 안정적인 서비스를 제공하기 위해 의도적으로 과도한 부하를 주어 진행된 스트레스 테스트(Stress Test)를 완벽하게 통과했습니다. 이로써 모든 점검 및 최적화 작업이 완료되었고, 카카오뱅크의 ‘나의 하루 응원받기 서비스’는 마침내 mini 고객에게 소개될 준비가 되었습니다.
실제 서비스 적용 후 사후 분석 (feat. 일기 생성 시간)
서비스는 오픈까지의 과정도 중요하지만, 오픈 후의 운영에서도 다양한 인사이트와 교훈을 얻을 기회가 많습니다. mini 일기 서비스가 시작된 후, ChatGPT의 처리 시간 즉, 일기 생성 시간 데이터에 주목했는데요. 이러한 데이터를 리전 별, 그리고 mini 체크카드 사용 건수 별로 세분화하여 분석하면서 추가적인 정보를 얻을 수 있었습니다. 각 그래프에서 가로축은 퍼센타일(percentile, % ile), 세로축은 시간(seconds, 초)으로 구성되어 있습니다.
퍼센타일(percentile)은 사람, 점수 등을 순서대로 나열했을 때, 그 중 어디에 위치하는지를 백분율로 나타내는 방법입니다. 예를 들어, 80번째 퍼센타일이라고 하면, 그 위치는 전체 중에서 상위 20% 안에 들어간다는 것을 의미하죠. 이런 식으로, 퍼센타일은 데이터의 분포와 개인의 위치를 이해하는 데 유용하게 사용됩니다.
⏰ 리전 별 일기 생성 시간
먼저 서비스 오픈 후, ChatGPT 3.5 0301 모델의 5개 리전 별로 일기 생성에 소요되는 처리 시간을 추적해 보았습니다. 신기하게도 같은 ChatGPT 3.5 0301 모델을 사용했음에도 리전별로 미세한 차이가 존재했는데요. [그림 4]의 왼쪽 그래프(‘리전 별 일기 생성 시간’)에서 확인할 수 있듯이, 서비스 운영 중 95% ile을 기준으로 할 때, 대부분의 일기 생성이 6초 이내에 이루어졌습니다. 5개의 리전을 놓고 등수를 확인해 보면, UK South 리전의 처리 시간이 가장 빠르고, France Central 리전이 가장 느렸습니다.
그렇지만 리전과의 단순 직선거리만으로는 일기 생성 처리 시간의 차이를 명확히 파악하기 어려웠습니다. 따라서 단순 거리에 의한 한계를 극복하기 위해 다른 요소에 더 집중했는데요. 예를 들어, 서비스가 불가능한 경우와 리전별 일기 생성 요청 처리량을 고려하여, 리전별로 트래픽 가중치를 주어 분산하는 방식의 기능을 구현해 활용했습니다.
⏰ mini 체크카드 사용건수 별 일기 생성 시간
mini 체크카드 사용건수가 일기 생성을 위한 처리 속도에 영향을 어떠한 영향을 미칠지에 대해서도 궁금했는데요. 이를 위해 체크카드 사용건수 별로 ChatGPT의 일기 생성 시간을 분석해 보았습니다. 처음에는 체크카드 사용 건수가 처리 속도에 영향을 미칠 것으로 예상되었지만, 생각보다 유의미한 차이가 나타나지 않았습니다. 물론, 사용 건수가 증가함에 따라 프롬프트에 입력되는 문자열의 길이는 다소 길어졌지만, 전체적인 처리 흐름은 유사했으며 병목 현상은 확인되지 않았습니다.
마무리하며
최근, 기업들 사이에서 ChatGPT의 사용이 기존 수준을 넘어 급격하게 증가하고 있습니다. 카카오뱅크에서 mini 일기 서비스를 개발하면서, 저도 ChatGPT의 활용 사례와 성능 분석, 관련 논문을 꼼꼼히 리서치해보곤 했는데요. 개발 과정에서 여러 난관에 부딪혔을 때마다 가능한 최선의 해결책을 찾아 적용하려 노력했지만, 종종 ChatGPT를 이용한 서비스 구축에 대한 정보가 부족해 막막함을 느낀 적도 많았습니다. 이 글이 ChatGPT 기반 서비스 개발에 관심 있는 분들에게 도움이 될 만한 참고 자료가 될 수 있기를 바랍니다. 마지막으로, mini 일기 서비스 개발 과정에서 얻은 ChatGPT 모델 선정 및 성능 테스트를 위한 팁을 정리해 공유드립니다.
- ✔️ ChatGPT 모델의 성능 차이를 파악하고, 서비스 품질에 따라 적합한 모델을 선택해야 합니다.
- ✔️ 서로 다른 ChatGPT 모델을 사용하는 경우, 서비스 품질이 달라질 수 있습니다.
- ✔️ ChatGPT 서비스 개발 시 실패 가능성을 항상 고려하여, 이를 관리하는 방안을 마련해야 합니다.
- ✔️ 리전별 분산 처리를 통해 ChatGPT는 더 많은 서비스 요청을 처리할 수 있으며, 각 리전의 실패에 대비한 Backoff 전략을 세워야 합니다.
- ✔️ 리전별로 ChatGPT의 성능 차이가 있으므로, 성능에 따른 가중치를 적용하여 트래픽을 적절히 분산할 수 있습니다.
- ✔️ 프롬프트에 사용되는 데이터의 크기는 서비스에 영향을 미칠 수 있지만, 이번 경우에는 데이터 크기의 변동이 큰 영향을 주지 않았습니다.
AI의 지속적인 발전과 함께, 앞으로 등장할 다양하고 흥미로운 서비스들을 기대해 봅니다. 빠르게 변화하는 기술 환경에서 여러분도 ChatGPT를 활용하여 새롭고 유용한 서비스를 개발하시길 응원하면서 마무리하겠습니다. 감사합니다.