신입 DevOps 엔지니어의 AI/ML 기반 자동화된 스팸 필터링 도입 경험기
안녕하세요, 인프랩 데브옵스 엔지니어 포카입니다.
어느덧 저의 첫 회사인 인프랩에 합류한 지 3개월이 지나가는데요!
오늘은 전문 직군 (AI/ML) 없는 저희 같은 스타트업에서 머신러닝/AI를 활용하여 자동화된 스팸 필터링 시스템 도입과 개선 과정을 소개해보려고 합니다.
인프런 스팸 필터링의 시작
스팸 문제의 대두
인프런이 성장하면서 다양한 스팸성 콘텐츠가 올라오기 시작했습니다. 초기에는 운영팀에서 수작업으로 이러한 게시글을 하나하나 검토하고 스팸으로 처리했습니다.
그러나 플랫폼이 확대됨에 따라 수작업으로 모든 게시글을 관리하는 것은 점점 비효율적이고 시간이 많이 소요되는 작업이 되었습니다.
초기 대응: GPT와 금지어 목록 활용
첫 번째 시도
데브옵스 팀의 제이크와 제이스께서 GPT-4o-mini
모델과 금지어 목록을 사용하여 스팸 여부를 판단하는 시스템을 구축했습니다.
이러한 선택의 이유는 스팸 필터링의 초기 단계였기 때문에 비용 효율적인 접근이 필요했습니다.
스팸 패턴을 찾아내는 방식으로 새로운 스팸 패턴이 발견되면 프롬프트 백오피스에 예제 데이터를 추가하는 Few-Shot 방식을 통해 스팸 필터링을 개선했습니다.
한계점
이 방법은 특정 패턴의 차단에는 유용했지만 새로운 스팸 유형이 발견될 때마다 직접 패턴을 추가해야 하는 제약이 있었습니다.
또한 특정 게시판에 자주 올라오는 스팸 패턴을 기준으로 예제 데이터와 금지어를 추가했기 때문에 모든 게시판에 일관되게 적용하기는 어려웠습니다.
게다가 스팸 필터링 초기 단계에 저렴한 모델을 사용하다 보니 저수준 AI의 스팸 글을 효과적으로 차단하지 못한다는 한계가 있었습니다.
머신러닝 도입: 적응형 스팸 필터
머신러닝을 통한 자동화
다음 단계로 새로운 스팸 유형을 학습하고 처리할 수 있는 적응형 스팸 필터를 구축했습니다.
스팸을 보다 확실하게 추출하기 위해 스팸 글에서 의미 없이 사용되는 단어의 가중치를 줄이고 중요한 단어만 추출하기 위해 TfidfVectorizer
를 사용하여 데이터를 벡터로 변환하였습니다.
여기서 벡터화를 진행하는 이유는 텍스트 데이터를 벡터로 변환하면 각 단어를 숫자 값으로 매핑하여 텍스트의 특징을 수치화시킬 수 있기 때문입니다.
쉽게 말해 방대한 텍스트를 지도 위에 표시해 중요한 위치만 명확히 보이도록 하는 과정과 비슷합니다.
신규 게시글의 벡터가 스팸 게시글의 벡터와 가까울 수록 유사한 것으로, 스팸 게시글일 확률이 더 크다고 볼 수 있겠습니다.
이러한 전처리 작업들로 머신러닝 모델이 데이터를 효과적으로 처리하고 분석할 수 있도록 기반을 마련했습니다.
모델 선택 배경
- 데이터 셋 제약: 당시 사용 가능한 데이터셋의 양이 많지 않아 적은 양으로도 학습이 가능해야 했습니다.
- 계산 속도: 스팸 게시글이 작성된 이후 최대한 빠르게 이를 가려야 일반 사용자분께 주는 피해를 최소화할 수 있어 빠른 계산 속도가 필요했습니다.
- 지속 학습 가능성: 새로운 스팸 유형이 추가되더라도 지속적으로 학습이 가능해야 했습니다.
- 모델 용량 제약: 모델의 용량이 늘어나지 않아야 했습니다.
위와 같은 조건에 적합한 모델로 SGDClassifier
를 선택했습니다.
해당 모델은 필요로 하는 연산량이 크지 않아서 GPU 없이 CPU만으로도 빠른 속도로 추론이 가능했습니다.
게시글 작성 이벤트는 특정 시간대에 집중되는 패턴을 띄므로, 상시로 서버를 실행하는 것 대신에 서버리스 함수에서 이벤트 기반으로 동작하도록 설계했습니다.
최초 모델 학습은 로컬 환경에서 약 2~3시간 동안 진행되었습니다.
실제 배포 환경에서, 서버리스 함수인 AWS Lambda에서 동작할 수 있도록 TfidfVectorizer
와 SGDClassifier
를 포함한 scikit-learn 라이브러리를 Lambda Layer로 추가했습니다.
덕분에 파이썬 코드 수정사항이 있을 때 코드만 빠르게 배포할 수 있었습니다.
파이썬 + Lambda Layer 조합 덕분에 콜드 스타트는 약 2.8초였고,
한 번 활성화되면 피크 시간대에는 대부분 콜드 스타트 없이 실행되는 걸 확인할 수 있었습니다.
그 결과 1,024 MB의 메모리를 부여한 Lambda 함수에서, 모델 추론에는 0.2 ~ 0.6 밀리초밖에 걸리지 않습니다.
학습된 벡터 및 모델 파일은 S3에 저장해 활용하고 Jenkins Cron Job으로 신규 게시글을 주기적으로 모델에 추가 학습시킴으로써 새로운 유형의 스팸에도 자동으로 적응할 수 있도록 구축했습니다.
스팸 필터링 프로세스
- 게시물이 생성될 때마다 SNS Topic을 발행.
- 해당 Topic이 SQS에 전달됨.
- SQS는 스팸 필터링 Lambda를 호출.
- 머신러닝 모델이 스팸 여부를 판단.
판별 프로세스
머신러닝을 도입하면서 스팸 검출 과정에 ‘스팸’, ‘의심’, ‘정상’이라는 세 가지 단계를 추가했습니다.
각 단계는 고유한 임계치를 설정하여 콘텐츠를 평가합니다. 만약 게시물이 ‘스팸’ 단계의 임계치를 초과하면 스팸으로 확정합니다.
실시간 모니터링
‘스팸’ 또는 ‘의심’ 단계로 분류된 경우에는 운영팀에서 실시간으로 상황을 모니터링할 수 있도록 Slack에 알림이 전송되도록 구성했습니다.
다국어 스팸 대응: ChatGPT의 도움
다양한 언어 지원
머신러닝 모델이 한국어와 영어에서는 뛰어난 성능을 보였으나 태국어, 몽골어, 중국어, 일본어 등 다양한 언어로 된 스팸 게시물에서는 어려움을 겪었습니다.
새로운 접근 방법
머신러닝과 ChatGPT를 결합하여 다국어 스팸에 대해 대응 할 수 있는 방안을 마련했습니다.
또한 효과적인 스팸 판별을 위해 GPT에게 아래와 같은 프롬프트를 입력하였습니다.
- 역할
- 콘텐츠 심사 전문가
- 하는 일
- 입력되는 콘텐츠를 스팸 혹은 정상으로 분류
- 스팸으로 간주하는 경우
- 광고, 홍보, 기만적인 내용 포함
- 단순 오타나 일반적인 주제는 스팸으로 간주하지 않음
- 정상 데이터로 간주하는 경우
- 정상적인 대화
- 불명확한 대화
- 출력 형식
-
{ "is_spam": 0 or 1, "reason": "스팸으로 판단한 이유를 50자 내로 한국어로 서술" }
-
해당 프롬프트를 입력하므로써 GPT에게 해야하는 일을 분명하게 명시하여 스팸 판별을 확실히 하고 출력 형식을 고정하여 토큰량을 줄이도록 하였습니다.
의심 유형 스팸 처리 프로세스 간소화
게시글이 ‘의심’ 단계로 분류된 경우 운영팀에서는 직접 확인 후 admin 페이지에 접속하여 게시글과 유저를 차단하고 확인을 위해 🅱️ 이모지를 추가했는데요.
이를 간소화하기 위해 스팸 의심 알림에 🅱️ 이모지가 추가되면 자동으로 해당 게시글과 유저가 차단되도록 구축했습니다.
스팸 유형 변화에 따른 새로운 대응 방안
새로운 스팸 유형
스팸 콘텐츠 차단이 개선되면서 일반적인 글인 척 관련 없는 링크를 삽입하거나 경험담인 척하는 홍보 글 등 다양한 스팸 유형들이 나타나기 시작했습니다.
이를 효과적으로 차단하기 위해 당근 테크 밋업에서 공개하였던 Zero Shot With Auto Generate Prompt
기법을 적용하기로 했습니다.
데이터 특징 추출 프롬프트
각 카테고리별 기존의 스팸 데이터와 정상 데이터를 기반으로 각각의 특징을 좀 더 상세하게 추출하기 위해 GPT-4o 모델을 사용하여 분석하고 그 결과를 MongoDB에 저장하였습니다.
주 1회, Jenkins Job에서 해당 기존 특징과 지난 주 스팸, 정상 데이터들의 특징을 비교하여 새로운 특징이 존재하면 특징을 추가하도록 설계하였습니다.
또한 특징 추출시 홍보성 글을 자동으로 스팸 처리해야 하지만, 학습자의 프로젝트 결과물 공유와 같은 일반적인 커뮤니티 활동은 스팸 처리 하면 안되는 등 여러 조건의 엣지 케이스들을 고려하며 과도한 일반화를 피하고 false positive를 줄일 수 있도록 명시하였습니다.
스팸 확인 프롬프트
이러한 방식으로 MongoDB에 저장된 특징을 조회하여 GPT-4o-mini
의 프롬프트에 포함하고 각 카테고리에 대한 관련성, 그리고 학습자의 프로젝트 결과물 공유와 같은 일반적인 커뮤니티 활동 등을 단계별로 판별하여 정확도를 높였습니다.
성과
자동화된 스팸 처리 시스템이 도입되고 그간의 많은 문제들이 해소 되었습니다.
스팸 처리수
매일 수기로 처리되는 대부분의 스팸처리를 이제는 대부분 자동으로 처리하고 있으며, 수기는 아주 소수의 건에 대해서만 처리되고 있습니다. 이로 CX 팀의 적극적 지지도 얻게 되었습니다.
스팸 계정 가입수
자동화된 스팸 계정 처리로 인해 더이상 스팸 게시글을 작성하는게 무의미 하다고 판단한 것인지, 스팸 계정을 생성하는 요청이 점점 줄어들어, 현재는 매일 생성되는 스팸 계정수가 시스템 도입 전/후 비교에 76%가 감소하였습니다.
비용
이렇게 대량의 리소스를 사용하는 솔루션은 비용이 꽤나 많이 들 것이라고 많이들 생각하시는데요. 저희가 구축한 AWS Lambda, SNS, SQS, S3 그리고 ChatGPT API 비용을 전부 합쳐도 게시글 1건의 스팸 여부를 판단하는데 단돈 0.05원밖에 들지 않는 것을 확인했습니다.
마무리
이번 글에서는 인프런이 직면한 스팸성 게시글 문제를 해결하기 위한 자동화된 스팸 필터링 시스템의 발전 과정을 공유했습니다.
처음에는 금지어 포함 여부를 확인하던 단순한 구조에서, ChatGPT를 사용하여 스팸 패턴을 감지하도록 하고
더 나아가 머신러닝 모델과 ChatGPT를 결합하여 다양한 유형의 스팸을 필터링할 수 있도록 개선했습니다.
이러한 개선을 통해 매번 새로운 유형의 스팸을 자동으로 차단할 수 있게 되어 서비스 운영 조직의 수고를 덜고,
저품질 링크로 향하는 스팸 게시글을 제거하여 SEO 지표를 개선하는 등의 효과 또한 얻을 수 있었습니다.
향후에는 프롬프트 백오피스를 고도화하여, 서비스 운영 조직에서도 쉽게 스팸 게시글 특징을 확인 및 수정할 수 있도록 시스템을 개선할 계획입니다.
지금까지 인프런 스팸 필터링 일대기에 대해 공유하였습니다.
읽어주셔서 감사합니다.