이전 Pretty Nail 프로젝트의 한계
PrettyNail 프로젝트는 교조증(손톱을 물어뜯는 습관)을 개선하기 위해, 손톱을 물어뜯는 행동을 감지해 경고를 주는 AI 프로젝트다.
이를 구현하기 위해, 아래와 같은 여정 밟아 왔다.
하지만 손톱을 물어뜯는 자세는 사람들마다 매우 다양하며, 복잡한 형태를 가진다. 단순 AI 로직으로는 높은 수준의 성능을 기대하기 어렵다. 가령, 턱을 괴는 모습과 손톱을 물어뜯는 행동조차도 쉽게 구별해 내기 힘들어한다. 때문에, 과거 PrettyNail의 로직은 사용성 측면에서 아쉬움이 있었다.
그러다 최근 우아한형제들의 테크 밋업(우아콘)에서 PrettyNail의 성능을 대폭 개선시킬 수 있는 힌트를 얻을 수 있었다. 이번 글에서는 이 힌트를 적용해 나간 과정, 그래서 정말 사용성을 개선시킬 수 있었는지 공유해 보려 한다.
ChatGPT가 복잡한 이미지도 분석할 수 있다? (feat, 배민 사례)
LLM의 해라 볼 수 있는 2024년, 역시나 우아콘에서도 LLM 관련 세션이 여럿 있었다. 그 중에서 가장 인상 깊게 들은 세션은 프롬프트 엔지니어링으로 메뉴 이미지 품질 검수하기이다.
배달의민족에서 사장님이 메뉴를 등록하면 메뉴 사진에 대해서 사람이 일일이 검수를 해야 했지만, GPT를 활용한 AI 이미지 검수 기능을 도입해 검수 시간을 99.98% 단축하고 상세한 반려 사유를 제공하여 사장님의 메뉴 등록 편의성을 높인 사례다.
사실 ChatGPT가 이미지를 생성하고 분석할 수 있다는건 꽤 오래전 일이지만, 분석의 디테일을 향상시키 위해 프롬프트를 세밀하게 개선해 나간 과정이 매우 인상 깊었다.
이 세션을 듣고, 한동안 멈춰왔던 PrettyNail 프로젝트가 생각났다. 배민에서 ChatGPT를 활용해 복잡한 메뉴 이미지를 분석했다면, 손톱을 물어뜯는 행동 여부를 판단하는 것도 충분히 가능할 일 아닌가? 집에 돌아와서 바로 ChatGPT를 PrettyNail에 도입해 보기로 했다. (멋진 기술 사례를 공유해 주셔서 감사합니다, 우아한형제들 파이팅!)
LLM으로 손톱 물어뜯는 상황을 판단하기 위한 여정
[GPT 호출 기준]
GPT에게 매 순간마다 손톱을 물어뜯는지 여부를 물어볼 순 없다. 의심이 될 때만 물어보는 게 효율적이다.
그 의심의 기준을 기존 PrettyNail의 로직을 활용할 수 있다.
- 손톱과 입술 사이의 거리가 가까운가?
- 손에 무언가를 들고 있는가?
1번과 2번 로직은 구글의 Mediapipe를 활용하면 비교적 작은 모델로도 쉽게 구축할 수 있다.
이렇게 1번과 2번 로직을 통과한 상황에만 GPT를 호출하여 최종 판단을 받게 되도록 로직을 구상하였다.
[GPT Prompt]
이미지와 함께 판단을 요청하는 프롬프트를 작성해 줘야 한다. 초기에는 손톱을 물어뜯는 상황을 세부적으로 정의해 줬다. 예를 들어, "입술이 벌어져 있어야 하며 손톱이 입 안에 들어가 있는 경우에만 물어뜯는 행동으로 간주"와 같은 조건을 말이다. 하지만, 지나치게 세부적인 조건이 포함된 프롬프트는 오히려 모델의 판단을 제한하여(오버피팅의 일환) 비정형적인 손톱 물어뜯기 행동을 놓치는 문제가 있었다.
오히려, GPT에게 전문가 역할을 부여하고 단순하면서도 명확한 프롬프트가 정확도가 좋았다. 최종적으로 다음과 같은 프롬프트를 사용하여 정확도를 향상했다. (기본적으로 ChatGPT는 한국어 보다 영어를 더 잘 이해하며, 손톱을 물어뜯는 행동은 언어와 독립적이기에 영어로 프롬프트를 진행했다.)
You are an advanced image analysis assistant with a strong focus on behavioral observations. Your expertise lies in evaluating subtle physical actions, particularly those related to nail-biting behavior. Your task is to evaluate whether the person in the provided image is biting their nails. Please observe the image thoroughly and provide your judgment based on the outlined criteria.
[GPT Parameter 최적화]
일관되면서도 냉정한 판단을 내릴 수 있도록 temperature 값을 조정했다. 초기에 temperature를 0.7로 설정했을 때, 같은 이미지에 대해 판단 결과가 달라지는 경우가 빈번히 발생했다. temperature가 높을수록 더욱 다채롭고 창의적인 답변을 생성해 내는데, 손톱을 물어뜯는지 여부를 판단하는 데는 필요한 요소가 아니었다. 직접 실험해 본 결과 temperature가 0일 때 가장 정확도가 좋았으며 같은 사진에 대해 일관적인 판단을 내렸다.
[GPT Output 구조 정의]
일반적으로 ChatGPT의 출력형식은 매우 자유롭다. "네 손톱을 물어뜯고 있네요", "손톱 물어뜯고 있음", "현재 오른쪽 손의 손톱을 물어뜯고 있는 것으로 판단됩니다." 등 동일한 판단 결과를 자연어로 풀어내기에 시스템으로 통합하기에 제한이 있었다. 일관된 판단 결과를 얻기 위해, 출력값을 Pydantic 스키마로 구조화했다. 이 스키마는 판단 결과를 Boolean 값으로 반환할 수 있도록 해준다. (물어뜯고 있다 : True, 아니다 : False)
class IsNailBiting(BaseModel):
is_biting: bool = Field(
description="Indicates whether the person is biting their nails",
example=True
)
[GPT API 비용 및 추론 시간 절감]
ChatGPT API 호출은 과금이 발생하며, 특히 이미지 분석은 텍스트에 비해 추론시간이 길어질 수밖에 없다. 이 둘을 동시에 줄일 수 있는 요소는 이미지의 사이즈를 줄이는 것이다. 보통 ComputerVision에서 이미지 사이즈를 줄이는 것은 정보의 양을 줄이는 것과 마찬가지라, 성능에 악영향을 끼칠 수 있다. 하지만, 자체적으로 수집한 200개의 테스트 셋에 대해서는 손톱 물어뜯는 여부를 이미지 사이즈와 상관없이 동일한 정확도를 보였다. 이미지 사이즈를 최대한 줄여, 추론 비용과 시간을 절감할 수 있었다.
[효율적인 경고 시스템 구축]
사실 PrettyNail의 정확도만큼이나 중요한 것은, 어떤 방식으로 경고를 줄 거냐? 였다. 잘 판단했으면 즉각적으로 경고를 주어 더 이상 물어뜯지 않도록 하는 게 가장 큰 목표였기 때문이다. 고민해 본 결과, 해당 로직을 내 맥북에서 동작할 수 있도록 하였다. 출근부터 퇴근, 그리고 집에서 공부할 때까지, 맥북의 카메라는 항상 나를 보고 있기에, 가장 적합하다고 생각했다. 맥북의 단축어 기능을 활용하면 python 코드로도 맥북의 화면을 직접 조절이 가능했다. Python으로 작성된 위의 로직이 손톱을 물어뜯는 행동을 감지하면, 단축어 기능을 호출하여 노트북 화면 밝기를 100%에서 10%로 급격히 낮추는 방식으로 경고를 전달했다. 이렇게 하면 주변 소음이나 물리적인 방해 없이도, 즉각적으로 손톱을 물어뜯고 있다는 사실을 인지할 수 있도록 해준다.
마무리
최종적으로 위의 로직을 적용해 본 결과, 손톱 물어뜯는 판단 정확도가 (구) PrettyNail에 대비해 약 1.35배 향상할 수 있었다.
손톱 물어뜯는 행위를 판단하는 것이 꽤 단순해 보이지만, 실제로는 인지적 판단이 필요할 만큼 복잡한 형태를 가진 행동이다. 이러한 행동을 정확히 분류해 내는 것은 기존의 전통적인 알고리즘으로는 쉽지 않은 과제다. 하지만 GPT를 비롯한 LLM(대규모 언어 모델)은 이러한 복잡한 문제에서 강력한 해법을 제시한다. 마치 사람처럼 추론하고 이해하며, 정형화되지 않은 문제를 유연하게 해결할 수 있기 때문이다. 이제는 어떤 문제가 주어지든, 해결책의 첫 번째 선택지로 LLM을 고려해야 할 시점이란 걸 온 몸으로 직접 느낀 순간이다.
'Tech > 손톱 물어뜯기 교정 AI' 카테고리의 다른 글
Pretty_Nail - AI로 어떻게 손톱 물어뜯는걸 인식할까? (1) | 2024.05.01 |
---|---|
Pretty_Nail - 너 그게 맛있냐? (0) | 2024.04.14 |