GCP Vision API(Product Search)를 활용한 이미지 기반 상품 추천 서비스 구축

오관영
29CM TEAM
Published in
13 min readApr 5, 2023

안녕하세요. 29CM Data Growth 팀 데이터 엔지니어 오관영입니다. 현재 29CM에서는 다양한 사용자 행동 데이터와 상품 메타 데이터를 활용하여 추천 시스템을 운영하고 있습니다. 이번 포스팅에서는 GCP Vision API(Product Search) 서비스를 활용하여 적은 리소스로 단기간에 이미지 기반 상품 추천 파이프라인을 구축한 과정을 소개하도록 하겠습니다.

이미지 기반 상품 추천의 필요성

29CM에서 이미 사용자의 행동 기반 데이터로 다양한 추천 서비스를 제공하고 있지만 상품의 색상이나 소재와 같은 상품 고유의 특성 데이터를 활용하여 유사한 스타일의 상품을 추천하고자 하는 니즈가 있었습니다.

하지만 현재 구축된 GCP Recommendation AI 서비스로는 커스텀한 모델 생성과 세부적인 컨트롤이 불가능하였고 데이터웨어하우스에 적재된 상품의 색상, 소재, 특징에 대한 메타 데이터도 정형화되어있지 않아 바로 사용이 어려운 문제점이 있었습니다.

이러한 문제점들을 해결하기 위해 사용자가 관심있는 상품의 이미지를 통해 해당 상품의 특성을 추출하고 유사한 스타일의 상품을 추천해줄 수 있는 이미지 기반 상품 추천 서비스가 필요했습니다.

Vision API(Product Search)

Vision API를 선택한 이유

데이터 팀에서는 자체적인 MLOps 환경 구축과 이미지 기반 모델 생성 전에 일차적으로 이미지를 기반으로 한 추천이 현재 서비스하고 있는 다양한 추천들과 비교해 어느 정도 효과가 있는지를 빠르게 파악해보는 것이 중요했습니다.

따라서 구축 리소스가 적고 빠르게 사용할 수 있는 다양한 클라우드 플랫폼의 관리형 서비스들과 Third Party 솔루션들을 검토하였고 아래 세 가지 이유로 Vision API를 선택하게 되었습니다.

1.모델 학습, 서빙에 필요한 인프라 구축 리소스 없이 사용 가능

  • 사전 학습된 모델 사용 가능
  • 별도 설정 없이 모델 서빙 가능

2. 다양한 상품 카테고리 영역 제공

  • 의류, 일반 제품, 가정용품, 장난감 등 여러 카테고리를 지정해서 상품 인식 가능

3. 데이터 팀에서 사용중인 GCP 서비스와 쉽게 연동 가능

  • 데이터웨어하우스(빅쿼리)
  • 데이터레이크(GCS)
  • Workflow(Composer)

Vision API(Product Search) 란?

Vision API(Product Search)는 GCP에서 제공하는 이미지 기반 검색 서비스입니다.

머신러닝과 이미지 인식 기술을 활용하여 이미지에서 상품을 식별하고, 사용자가 생성한 상품 세트에서 유사한 상품을 매칭할 수 있는 기능을 제공합니다.

출처: Cloud Vision API

위 그림과 같이 사용자가 관심있는 상품의 이미지를 Vision API를 통해 전달하기만 하면 해당 이미지에서 인식된 상품과 상품 세트에 등록된 상품들의 이미지를 매칭하여 유사한 상품을 조회할 수 있습니다.

따라서 실제 서비스를 사용하기 위해 필요한 부분은 상품 이미지 적재와 상품 세트 구성 두 가지 뿐이며 그 외 별도로 MLOps 환경을 구축할 필요가 없습니다.

도입 과정과 비슷한 맥락이지만 데이터 팀에서 Vision API를 실제로 사용하면서 느꼈던 장점과 단점을 간략하게 요약하면 다음과 같습니다.

장점

  • MLOps 인프라 구축 리소스, 운영 비용 없이 서비스 사용 가능
  • 다양한 카테고리의 상품 인식 가능
  • 다양한 GCP 서비스와 연동 가능(Vertex AI Vision, GCS, Bigquery 등)

단점

  • GCP 콘솔로 관리 불가능
  • 사전 학습된 모델에 추가 학습이나 커스터마이징 불가능
  • 높은 서비스 호출 비용

파이프라인 구성

Vision API를 사용하기 위해 전반적인 파이프라인을 아래 그림과 같이 구성하였습니다.

29CM Vision API Pipeline
29CM Vision API Airflow DAG

Airflow(Composer)의 PodOperator를 통해 쿠버네티스(GKE) 클러스터에 파드를 생성하여 상품 이미지를 GCS에 적재하고 새로 등록되거나 업데이트된 상품의 상품 번호, 카테고리, 이미지 정보 등의 메타정보를 기반으로 Vision API 상품 세트를 생성하고 업데이트하는 작업을 수행합니다.

이때 필요한 상품의 메타정보와 상품 이미지는 데이터레이크(GCS)와 데이터웨어하우스(Bigquery)에 적재된 데이터를 사용합니다.

이러한 파이프라인은 신규로 등록된 상품과 이미지, 카테고리 등 메타 정보가 업데이트된 상품을 Vision API와 매시간 동기화합니다.

다음으로는 파이프라인에서 수행되는 개별 작업과 유사한 상품 이미지를 확인하는 방법에 대해 자세하게 설명 드리도록 하겠습니다.

1. 상품 이미지 수집 및 적재

Vision API는 GCS에 적재된 이미지만 연동이 가능하기 때문에 반드시 상품 이미지를 GCS에 적재하는 과정이 필요합니다.

파이프라인 구축 당시 이미 AWS S3에 모든 상품의 이미지가 적재되고 있어 GCP Storage Transfer 서비스를 사용하여 S3와 GCS를 동기화하는 방법을 고려하였습니다. 하지만 아래와 같은 사용성에 문제가 있어 29CM의 이미지 서버에서 필요한 이미지만 추출하여 전처리 후 GCS에 적재할 수 있는 파이썬 코드를 직접 구현하였습니다.

필요한 이미지만 선택하여 동기화가 어려움

전체 이미지 중 실제 Vision API와 연동할 상품 메인 이미지는 20% 정도밖에 되지 않았고 Storage Transfer를 사용하면 불필요한 이미지들까지 모두 GCS에 동기화되는 문제

이미지를 전처리하여 다시 적재하는 과정 필요

Storage Transfer를 사용하면 S3에 적재된 원본 해상도의 이미지가 그대로 동기화되기 때문에 이미지 전처리 과정 후 다시 적재해야 하는 문제

2. 상품 세트 생성 및 Import

상품 세트에 대해 간략하게 설명드리면 상품 세트는 Vision API에서 관리하는 상품 카탈로그입니다.

검색할 상품의 이미지와 상품 세트 내에 등록된 상품의 이미지를 서로 매칭하여 유사한 상품 결과를 확인할 수 있으며 상품 세트와 연결된 개별 상품에 레이블을 설정하여 검색 결과 필터링에 유용하게 사용할 수 있습니다.

상품 세트를 생성하는 방법은 두 가지가 있습니다.

첫 번째는 API를 통해 빈 상품 세트를 생성하고, 개별 상품을 하나씩 import하는 방식입니다.

두 번째는 CSV 파일을 통해 상품 세트와 이와 연결된 상품을 동시에 생성하는 방식입니다.

두 방식 모두 구현은 간단하지만, CSV 파일을 통해 import 된 상품의 이력 관리가 가능하고 최대 20,000개의 상품을 bulk 형태로 import 할 수 있어 CSV 파일 import 방식을 선택했습니다.

상품 세트를 생성하는 CSV 파일 형식을 간단하게 살펴보면 아래와 같습니다.

  • image-uri

상품 이미지 URI입니다. GCS에 적재된 이미지 URI만 사용할 수 있기 때문에 사전에 상품 이미지를 GCS에 반드시 적재해야 합니다.

  • image-id

image-uri로 등록될 이미지의 ID 값을 사용자가 설정할 수 있습니다. 설정하지 않으면 자동으로 고유한 값이 할당됩니다.

  • product-set-id

생성할 상품 세트의 ID로 해당 값으로 상품 세트가 자동으로 생성됩니다.

  • product-id

상품 세트에 등록할 상품의 ID입니다.

  • product-category

이미지에서 상품을 식별하는 카테고리 값으로 homegoods-v2, apparel-v2, toys-v2, packagedgoods-v1, general-v1 중 한 가지를 선택 할 수 있습니다.

  • product-display-name

상품세트에 등록할 상품의 이름을 사용자가 지정할 수 있습니다.

  • labels

상품에 Key Value 형태로 레이블을 설정합니다. 설정된 레이블 값으로 검색 결과를 필터링 할 수 있습니다. 예를 들어 상품의 카테고리, 성별 구분 을 레이블로 설정하여 검색 결과에 필터로 사용 가능합니다.

  • bounding-poly

상품 이미지에서 관심 영역을 폴리곤 좌표로 사용자가 지정할 수 있으며 따로 설정하지 않으면 Vision API 내부에서 자동으로 관심 영역을 지정합니다.

상품 세트에 필요한 데이터는 GCS에 적재된 상품 이미지의 URI와 데이터 웨어하우스(Bigquery)에서 추출한 상품 메타 데이터를 합쳐 위에서 설명드린 상품 세트 포맷에 맞게 Transform 과정을 거친 후 CSV 파일을 생성합니다

이후 생성된 CSV 파일을 GCS에 매시간 적재하고 Vision API에 import 합니다.

이 과정에서 상품 세트에 등록할 상품이 20,000개 이상일 경우 자동으로 파일을 분리하여 import 하도록 구현하였습니다.

3. 상품 세트 업데이트

상품 세트에 이미 등록된 상품의 이미지나 카테고리와 같은 메타 데이터가 변경된 경우 해당 데이터로 상품 세트를 업데이트합니다.

29CM 서비스에서 Vision API 상품 세트에 사용자가 관심 있는 상품 이미지와 유사한 이미지 상품을 검색할 때 상품 세트 레이블에 설정된 카테고리 값을 사용해 동일한 카테고리 내 상품만 필터링하여 조금 더 세밀한 추천 결과를 제공하고 있습니다.

따라서, 상품 세트 업데이트 작업을 통해 데이터 웨어하우스의 상품 메타 데이터와 상품 세트 간에 데이터 불일치를 최소화하여 엉뚱한 카테고리 상품이 사용자에게 추천되는 상황을 방지하도록 구현하였습니다.

4. 상품 세트 검색 및 결과 확인

구성이 완료된 상품 세트에 아래 Endpoint를 통해 GCS에 적재된 특정 이미지와 유사한 이미지의 상품 결과를 확인할 수 있습니다.

  • Request
curl -X POST "<https://vision.googleapis.com/v1/images:annotate>" \\
-H "Authorization: Bearer $(gcloud auth print-access-token)" \\
-H "x-goog-user-project: {project_ID}" \\
-H "Content-Type: application/json; charset=utf-8" \\
--data '{
"requests": [
{
"image": {
"source": {
"gcsImageUri": "{gcs_image_URI}"
}
},
"features": [
{
"type": "PRODUCT_SEARCH",
"maxResults": 30
}
],
"imageContext": {
"productSearchParams": {
"productSet": "projects/{project_ID}/locations/{location_ID}/productSets/{product_set_ID}",
"productCategories": [
"apparel-v2"
],
"filter": "category = 남성의류 AND category = 아우터"
}
}
}
]
}'

위에서 설명드린 것과 같이 레이블에 설정한 카테고리 값을 filter 파라미터에 추가하여 상품 세트의 특정 카테고리 상품만 필터링하여 결과를 확인할 수 있습니다.

  • Response
{
"responses": [
{
"productSearchResults": {
"indexTime": "2023-03-27T02:36:00.204123419Z",
"results": [
{
"product": {
"name": "projects/{project_ID}/locations/{location_ID}/products/1679971",
"displayName": "MUSLIN POCKET BAG (WHITE)",
"productCategory": "apparel-v2",
"productLabels": [
{
"key": "category",
"value": "남성의류"
},
{
"key": "category",
"value": "아우터"
}
]
},
"score": 0.7178505,
"image": "projects/{project_ID}/locations/{location_ID}/products/1679971/referenceImages/1679971"
}
... ],
}
}
]
}

응답 결과로 유사한 이미지 상품 메타정보(ID, 상품명, 레이블 정보, 상품 세트에 등록된 이미지 ID)와 유사도 값을 확인할 수 있습니다.

아래는 실제 29CM의 상품 이미지와 유사한 이미지 상품 결과를 유사도 점수 순으로 가공한 결과입니다.

추가 개선 사항

29CM 서비스와 Vision API의 Endpoint를 연동하는 과정에서 당연하게도 서비스 트래픽과 비례해 호출 비용이 과도하게 발생하였고 비용을 최소화하기 위해 29CM API 서버에서 상품ID 기반으로 Redis Cache를 설정하여 50% 이상의 호출 비용을 절감하였고 지속적인 모니터링을 위해 대시보드를 구성하였습니다.

Redis Cache Hit 대시보드
GCP Vision API Request 모니터링

마치며

지금까지 Vision API를 통해 이미지 기반 상품 추천 서비스를 구축한 과정을 설명드렸습니다.

비록 커스텀한 모델 학습과 조정이 불가능하고 지속적으로 서비스를 사용하기에는 비용적인 부담이 크지만 MLOps 환경 구성이 당장 어려운 상황이거나 이미지 기반 추천의 효용성을 간단히 체크하기 위해서 Vision API 서비스를 활용한다면 굉장히 장점이 큰 서비스라고 생각합니다.

간단한 파이프라인 구축과정이라 엄청난 노하우나 기술을 설명드리진 못했지만 Vision API를 처음 접하시는 분들께 조금이나마 도움이 되었으면 좋겠습니다.

감사합니다.

29CM 비슷한 상품 추천

함께 성장할 동료를 찾습니다

29CM (무신사) 는 3년 연속 거래액 2배의 성장을 이루었습니다.

다양한 소스 데이터에서 안전하고 빠르게 수집, 처리, 저장, 제공하도록 파이프라인을 개발하고 운영하며, 제공된 데이터를 활용하여 데이터 기반 의사결정을 돕기 위해 다양한 대시보드를 제작 및 분석을 진행하고 있습니다. 데이터를 활용하여 가치를 창출하고 함께 성장할 동료 데이터 엔지니어 및 데이터 분석가를 찾고 있습니다.

많은 지원 부탁드립니다!

🚀 29CM 채용 페이지 : https://www.29cmcareers.co.kr/

--

--