졸업프로젝트(2024)

[졸업프로젝트] 어떤 번역 API를 쓰는 게 좋을까?

dulbong 2024. 10. 18. 02:09

 


💻졸업프로젝트 <보성말차> 팀 - Multimodal LLM을 통해 분실물을 쉽게 찾을 수 있는 서비스


 

교내 분실물 센터에서는 하나의 사진 안에 모든 분실물을 때려박아 (?) 업로드 하고 있다.

우리가 원하는 건 쉽게 말해 사진에 있는 물체를 자동으로 분류하는 것인데, 그러려면 먼저 생성형 LLM 모델이 물체를 인식해 특징을 출력해야겠다. 그런데 어떤 모델을 써야 성능이 좋을 지 잘 모르겠다.

 

 


👩🏻👧🏻🧒🏻 멘토님 도와주세요@!!

👦🏻 LLaVA, MiniGPT-4, deepseek

 
 

 

 



💻번역 API

멘토님께서 추천해주신 여러가지 패키지들은 <영어> 기준이었다.
한글로 prompt를 입력했을 경우에는 영어보다 성능이 좋지않게 나올 수 있으니 멘토님께서 추천해주신 방법은

  1. 한글로 질문
  2. 질문을 영어로 번역
  3. 영어로 출력된 결과를 한글로 다시 번역
  4. 한글로 번역된 결과를 출력

여기서 번역을 돕는 API는 여러가지가 있기 때문에 어떤 API를 올리는 것이 가장 좋은 성능을 보일지 직접 부딪혀보는 수 밖에는 없겠다.

 

https://jehyunlee.github.io/2023/02/20/Python-DS-128-transqual/

 

번역 모델을 비교해주신 좋은 글이 있길래 참고하였다.
직접 소요시간을 확인해보고 싶은데, 아쉽게 파파고는 서비스를 종료하였다.

일년만 늦게 종료하지...

 

 

 

그래서 위 글을 참고하여 아래 세 개 모델에 대해서 성능을 비교해보기로 한다.

  1. Google Translation API
    • 무료 (체험판)
    • 안정적인 성능
  2. Huggingface
    • 무료
    • 최신, 완성도 높은 모델
  3. OpenAI GPT3
    • 유료
    • 수행할 때마다 다른 결과
 
 


💻Google Colab

협업에 용이한 Google Colab에서 코드를 작성하기로.

 
 


💻Colab에 LLaVA를 올려보자

번역 성능을 비교하려면 번역할 문장이 필요하다. (당연함)
번역할 문장을 유명한 책이나 논문 초록에서 뽑아올까 생각했으나,
이왕이면 우리가 사용할 분실물 사진을 이용하는게 좋을 듯.

 

Segmentation 과정을 거치지 않은 원본 분실물 사진 데이터를 설명해줄 LLaVA를 Colab에 먼저 올려보자.

 

https://github.com/camenduru/LLaVA-colab/blob/main/LLaVA_7b_colab.ipynb

https://hypro2.github.io/llava-colab/

 

위의 두 링크를 참고해서 코드를 완성했다.
특히 아래 포스팅의 def caption_image(image_file, prompt) 함수를 눈여겨보았다.

우리 프로젝트에 맞게 약간의 수정을 거쳤다.

(감사합니다)

 

 

 

 

 

Colab에 LLaVA를 올리는 것, 쉽지않은 일이다.
생각보다 LLaVA가 무거워서 설치하는 데에만 몇십 분 이상 걸린다.

설치해놓고 잠깐 낮잠을 자자

 

Colab 내 '/content' 하위 폴더로 '/image'를 생성한다.
image 폴더에 분실물 사진을 저장한다.

저장한 분실물 사진의 예시

 

image_path = "/content/image"
file_list = [file_name for file_name in os.listdir(image_path) if os.path.isfile(os.path.join(image_path, file_name))]

prompt = "Please describe this image. Which objects are in this image?"

# 이미지 파일 읽어서 번역 후 출력
for file_name in file_list:
  images =(os.path.join(image_path, file_name))
  image, output = caption_image(images, prompt)

  print("파일명:"+file_name+"\n")
  print("본문: "+output+"\n")

 

 

LLaVA에게 의뢰한(?) 결과가 잘 나온다.

역시 결과는 영어로 나온다. 우린 한글에 익숙하니, 한글로 번역하도록 하자.

 

 

해당 결과를 각각의 translation API로 번역해보자.

 
 


💻실행 오류 발생 시

본격적인 설치에 앞서

 

만약 실행이 되지 않는다면 오류 로그를 확인해보고, 각 API 실행에 필요한 python 패키지를 맞는 버전으로 모두 설치했는지 확인해보자.

 

패키지 업그레이드 !pip install --upgrade 패키지명==버전

패키지 삭제 !pip uninstall 패키지명

패키지 설치 여부 확인 !pip list

 
 


💻Google Translation

!pip install --upgrade httpcore==0.15.* httpx==0.24.*
!pip install --upgrade googletrans==4.0.0-rc1

컴퓨터에 httpcore와 httpx, googletrans가 설치되어있지 않다면 --upgrade를 제외하고 실행하면 된다.

실행 코드

import os
from googletrans import Translator
from time import time

google = Translator()

image_path = "/content/image"
file_list = [file_name for file_name in os.listdir(image_path) if os.path.isfile(os.path.join(image_path, file_name))]

prompt = "Please describe this image. Which objects are in this image?"

# 이미지 파일 읽어서 번역 후 출력
for file_name in file_list:
  images =(os.path.join(image_path, file_name))
  image, output = caption_image(images, prompt)
  
  time_start = time()
  translation = google.translate(output, dest="ko")
  time_end = time()

  print("파일명:"+file_name+"\n")
  print("본문: "+output+"\n")
  print("번역문: "+translation.text+"\n")
  print(f"소요시간: {time_end-time_start:.2f}s")

결과

파일명:1.jpg

본문: The image features a spacious room with a variety of objects scattered across the floor. There is a spiral notebook, a Starbucks coffee cup, a cell phone, a laptop, and a power cord. Additionally, there are some stickers on the floor, adding to the cluttered appearance of the scene.

번역문: 이미지에는 바닥에 다양한 물체가 흩어져있는 넓은 방이 있습니다.나선형 노트북, 스타 벅스 커피 컵, 휴대폰, 노트북 및 전원 코드가 있습니다.또한 바닥에 스티커가 있으며 장면의 혼란스러운 모양이 추가됩니다.

소요시간: 0.87s
파일명:12.jpg

본문: The image features a variety of items laid out on a table or floor. These items include a package of noodles, a pair of scissors, a pen, a watch, and a cell phone. The objects are spread out, with some items placed closer to the front and others near the back. The scene appears to be a collection of everyday items, possibly for a craft project or a display of personal belongings.

번역문: 이미지에는 테이블이나 바닥에 배치 된 다양한 항목이 있습니다.이 항목에는 국수 패키지, 가위, 펜, 시계 및 휴대폰이 포함됩니다.물체는 펼쳐져 있으며 일부 품목은 전면에 가까워지고 다른 항목은 뒤쪽 근처에 있습니다.이 장면은 공예 프로젝트 또는 개인 소지품 전시를위한 일상적인 아이템 모음으로 보입니다.

소요시간: 0.53s
파일명:4.jpg

본문: The image features a white keyboard, a hat, and a sweater. The keyboard is placed next to the hat, and the sweater is positioned nearby. The objects are arranged on a surface, possibly a table or a floor.

번역문: 이미지에는 흰색 키보드, 모자 및 스웨터가 있습니다.키보드는 모자 옆에 배치되며 스웨터는 근처에 위치합니다.물체는 표면, 아마도 테이블 또는 바닥에 배치됩니다.

소요시간: 0.98s
파일명:13.jpg

본문: The image features a variety of objects laid out on a table, including a laptop, a keyboard, a mouse, a book, a cell phone, and a stuffed animal. The objects are arranged in a way that suggests they are being prepared for packing or organizing.

번역문: 이미지에는 랩톱, 키보드, 마우스, 책, 휴대폰 및 박제 동물을 포함하여 다양한 물체가 테이블에 배치되어 있습니다.물체는 포장 또는 구성을 준비하고 있음을 시사하는 방식으로 배열됩니다.

소요시간: 0.99s
파일명:2.jpg

본문: The image features a notebook and a pair of earbuds placed on a table. The notebook is open, and the earbuds are sitting next to it. The table appears to be a desk, and the objects are arranged neatly on its surface.

번역문: 이미지에는 노트북과 한 쌍의 이어 버드가 테이블 위에 놓여 있습니다.노트북이 열려 있고 이어 버드는 그 옆에 앉아 있습니다.테이블은 책상 인 것처럼 보이며 물체는 표면에 깔끔하게 배열됩니다.

소요시간: 0.50s

몇 가지 아쉬운 점이 눈에 띈다.

 

spiral notebook

  • 예상 결과 : 스프링노트
  • 실제 결과 : 나선형 노트북

earbuds

  • 예상 결과 : 이어폰
  • 실제 결과 : 이어 버드

전체적인 번역 퀄리티는 나쁘지 않으나, 평소 사용하지 않는 용어로 번역된 단어가 많아 '용어집' 사용 등을 고려해보는 것이 좋을 것 같다.

 

 



💻Huggingface

별도로 프로그램을 설치하거나 API를 받을 필요 없이 파이썬 패키지 설치로 사용할 수 있기 때문에 간단하다.

!pip install transformers sentencepiece -q

 

다만 아래와 같은 오류가 발생할 수 있는데,
A UTF-8 locale is required. Got ANSI_X3.4-1968


이런 경우에는 '!' 명령어 대신 파이썬에서 제공하는 'subprocess' 모듈을 통해 UTF-8 export, pip install을 진행해준다.

import subprocess

subprocess.run(['export', 'LC_ALL=C.UTF-8'], shell=True)
subprocess.run(['export', 'LANG=C.UTF-8'], shell=True)

subprocess.run(['pip', 'install', 'transformers', 'sentencepiece', '-q'])

실행

from transformers import pipeline

pipe = pipeline(task='text2text-generation', model='facebook/m2m100_418M')

image_path = "/content/image"
file_list = [file_name for file_name in os.listdir(image_path) if os.path.isfile(os.path.join(image_path, file_name))]

prompt = "Please describe this image. Which objects are in this image?"

# 이미지 파일 읽어서 번역 후 출력
for file_name in file_list:
  images =(os.path.join(image_path, file_name))
  image, output = caption_image(images, prompt)
  
  time_start = time()
  translation = pipe(output, forced_bos_token_id=pipe.tokenizer.get_lang_id(lang='ko'))
  time_end = time()

  print("파일명:"+file_name+"\n")
  print("본문: "+output+"\n")
  print(f"번역문: {translation[0]['generated_text']}"+"\n")
  print(f"소요시간: {time_end-time_start:.2f}s")

결과

파일명:1.jpg

본문: The image features a spacious room with a variety of objects on the floor. There is a notebook, a Starbucks coffee cup, a cell phone, and a book. Additionally, there are two cords and a small container on the floor. The objects are scattered around the room, creating a casual and relaxed atmosphere.

번역문: 그림은 바닥에 다양한 개체가있는 넓은 방을 갖추고 있습니다. 노트북, 스타벅스 커피 컵, 휴대 전화 및 책이 있습니다. 또한 바닥에 두 개의 코드와 작은 컨테이너가 있습니다.

소요시간: 19.87s
파일명:12.jpg

본문: The image features a variety of objects laid out on a table or counter. Among these objects, there is a package of noodles, a package of chocolate, a pair of scissors, a pen, a watch, and a cell phone. The items are spread out, and some are placed closer to the edges of the table. The scene gives the impression of a collection of everyday items, possibly for a craft project or a display of personal belongings.

번역문: 이 이미지에는 테이블이나 컨테이너에 놓인 다양한 개체가 있습니다.이 개체 중에는 노드 패키지, 초콜릿 패키지, 쌍의 분쇄기, 펜, 시계 및 휴대 전화가 있습니다. 항목이 퍼져 있으며 일부는 테이블의 가장자리에 더 가까이 배치됩니다.

소요시간: 25.18s
파일명:4.jpg

본문: The image features a variety of objects, including a white keyboard, a hat, a sweater, and a pair of glasses. The objects are placed on a table, creating an assortment of items.

번역문: 그림에는 화이트 키보드, 모자, 스위터, 그리고 안경 쌍을 포함한 다양한 개체가 있습니다.

소요시간: 9.29s
파일명:13.jpg

본문: The image features a variety of objects laid out on a table or a counter. There is a laptop computer, a keyboard, a mouse, a cell phone, and a book. Additionally, there is a stuffed animal, possibly a teddy bear, and a jacket. The objects are arranged in a way that suggests they are being prepared for a trip or a journey.

번역문: 그림은 테이블이나 카운터에 놓인 다양한 개체를 보여줍니다. 노트북 컴퓨터, 키보드, 마우스, 휴대 전화, 그리고 책이 있습니다. 또한, 포장 된 동물, 어쩌면 꼬마 곰, 그리고 재킷이 있습니다.

소요시간: 20.98s
파일명:2.jpg

본문: The image features a notebook and a pair of earbuds placed on a table. The notebook is open, and the earbuds are lying next to it.

번역문: 그림에는 노트북과 테이블에 놓인 쌍의 벽돌이 있습니다. 노트북은 열려 있으며 벽돌은 그 옆에 있습니다.

소요시간: 12.02s

굉장히 느리다.


앞서 Google Translation이 채 10초가 되지 않는 시간에 결과를 뽑았던 것과는 다르게 Huggingface는 최소10초?

번역해야할 문장이 많은 우리 프로젝트에는 적합하지 않아 보인다.

사용자가 업로드한 사진 한 장을 설명하는 데에 20초, 25초씩 걸린다면 아마 참을성이 없는 실사용자(나 포함)는 우리 서비스를 떠나버릴 게 분명하다.

 

번역의 성능은 어떨지 질적 평가를 해보자.

 

LLaVA 모델을 계속 새로 돌리다보니 Google Translation과 번역한 본문이 달라졌다는 것이 아쉬운데, 마지막에 같은 문장을 번역한 결과로 성능을 한번 비교해보도록 하자.

본문
The image features a variety of objects laid out on a table or a counter. There is a laptop computer, a keyboard, a mouse, a cell phone, and a book. Additionally, there is a stuffed animal, possibly a teddy bear, and a jacket. The objects are arranged in a way that suggests they are being prepared for a trip or a journey.

 

본문의 마지막 문장을 주목하자

번역문
그림은 테이블이나 카운터에 놓인 다양한 개체를 보여줍니다. 노트북 컴퓨터, 키보드, 마우스, 휴대 전화, 그리고 책이 있습니다. 또한, 포장 된 동물, 어쩌면 꼬마 곰, 그리고 재킷이 있습니다.

 

본문의 마지막 문장은 아예 번역하지 않았다.

번역의 퀄리티를 떠나 아예 문장을 번역하지 않는다는 것은 우리 프로젝트 결과에도 영향을 줄 수 있는 부분이다.

 

 



💻GPT

GPT에서 주목할 점은 앞선 번역 모델들과 달리, 실행할때마다 결과가 다르게 나온다는 점이다.

 

사전 준비

!pip install openai==0.28
!pip install httpx==0.23.0

 

또는

import subprocess

subprocess.run(['export', 'LC_ALL=C.UTF-8'], shell=True)
subprocess.run(['export', 'LANG=C.UTF-8'], shell=True)

subprocess.run(['pip', 'install', 'openai==0.28'])
subprocess.run(['pip', 'install', 'httpx==0.23.0'])

 

실행

import openai
openai.api_key = "본인의 API 키"

from functools import wraps

image_path = "/content/image"
file_list = [file_name for file_name in os.listdir(image_path) if os.path.isfile(os.path.join(image_path, file_name))]

prompt = "Please describe this image. Which objects are in this image?"

def timed(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        time_start = time()
        result = func(*args, **kwargs)
        time_end = time()
        print(f'- 소요시간: {time_end-time_start:.2f}s')
        return result
    return wrapper

@timed
def translateGPT(text, model="gpt-3.5-turbo-0613", max_tokens=1000, top_p=1.0):
    response = openai.Completion.create(
      model=model,
      prompt=f"Translate this in Korean:{text}",
      temperature=0.3,
      max_tokens=max_tokens,
      top_p=top_p,
      frequency_penalty=0.0,
      presence_penalty=0.0
    )
    return response.to_dict()['choices'][0]["text"].lstrip("\n")

for file_name in file_list:
  images =(os.path.join(image_path, file_name))
  image, output = caption_image(images, prompt)

  print("파일명:"+file_name+"\n")
  print("본문: "+output+"\n")
  print(f"번역문: {translateGPT(output)}")

 

결과

RateLimitError: You exceeded your current quota, please check your plan and billing details. 
For more information on this error, read the docs:
https://platform.openai.com/docs/guides/error-codes/api-errors.

 

Chat GPT는 과금 이슈를 해결하지 못해서 아쉽게 번역해보지 못했다.

등록금도 내는데 사비를 또 들여서 사용안할지도 모르는 Chat GPT에 결제할 수는 없었다.

다만 저예산으로 최고의 효율을 뽑아내야하는 대학수준 졸업프로젝트에서 <과금> 요소는 부담이 될 수 밖에 없다.

 
 


💻어떤 API가 좋을까?

 

  번역 성능 (상, 중, 하) 평균 번역 속도 과금 여부
Google Translation API
(대체적으로 좋은 번역 성능을 보이지만, 주로 사용하지 않거나 브랜드 이름, 관용적으로 사용하는 물건들의 이름은 제대로 번역하지 못하는 모습니다.)
1s 내
(0.9초 내외)
X
Huggingface
(번역해야하는 문장이 길어지는 경우 번역하지 않는 문장이 생긴다는 점이 치명적이었다. )
15s 내외
(10s ~ 20s)
X
Chat GPT
(무료로 Chat GPT를 사용했을 때, 한글로도 무리없이 답변을 내는 것을 생각해본다면 API 사용에도 높은 정확도를 보일 것이라고 생각한다.)
- O

 

결국 나는 Google Translation API를 선택하였다. 

 

무료이면서 빠른 속도, 가성비를 따져보면 괜찮은 성능이 선택 이유이다.

이정도면 사용자들에게 만족스러운 결과를 낼 수 있을 것 같고, 단어 번역이 아쉬웠으나 대학교 내에서 자주 잃어버리는 물건 등은 용어집을 적극적으로 활용해 번역 정확도를 높이도록 하겠다.