서론
TypeSafe의 Jev가 이미지 입력을 지원하게 되었습니다.
이 글에서는 Jev의 이미지 입력으로 무엇을 할 수 있는지 확인합니다.
나아가 OpenAI의 Decisions API에도 동일한 사진을 보내 정확도, 속도, 비용을 비교했습니다.
Jev의 이미지 입력으로 가능한 것들
System One의 요청에는 이미지를 포함할 수 있습니다.
이미지와 Box 질문은 기본적으로 비활성화되어 있으므로, 요청에는 TypeSafe-Danger-Zone-Images: true 헤더가 필요합니다.
이미지 등록 위치는 최상위 레벨의 assets입니다.
assets의 키를 이미지 참조 문자열로 사용합니다.
이 문자열을 state, 질문의 instructions, criteria에 설정하면, API가 참조를 이미지로 대체하여 모델에게 전달합니다.
참조 문자열은 문장 중간에도 작성할 수 있습니다.
문서에서 권장하는 전송 방식은 multipart입니다. base64로 JSON에 포함시킬 수도 있지만, 데이터가 약 3분의 1 증가하며, 이 부분도 요청 본문 상한선에 포함됩니다.
Noul, Choice, Score의 모든 질문 유형에서 이미지를 다룰 수 있습니다.
게다가 Box를 사용하면 대상 위치가 top, bottom, left, right로 반환됩니다.
이미지 입력은 Jev 1.13과 1.14 모두에서 사용할 수 있지만, Box는 Jev 1.14가 필요합니다.
이미지를 설정하는 파라미터에 따라 다음과 같이 활용할 수 있습니다.
| 할 수 있는 것 | 설정하는 파라미터 |
|---|
| 알려진 사진과 같은지 확인하기 | 대상은 state, 비교 사진은 instructions |
| 문장 기준 분류하기 | 사진은 state, 기준은 criteria의 문장 |
| 예시 이미지로 분류하기 | 대상은 state, 예시는 criteria |
| 프레임 간 변화 보기 | 오래된 순서의 배열을 state |
| 물체의 위치 찾기 | state. 찾는 물체의 사진을 instructions에 설정할 수도 있음 |
| 필요할 때만 확대해서 보기 | 먼저 작은 이미지를 state. 부족하면 큰 이미지나 잘라내기 |
| 큰 이미지를 분할하여 찾기 | 타일을 Choice의 criteria로 사용하기 |
Score의 각 단계나 Noul의 true/false에도 예시 이미지를 설정할 수 있습니다.
참조를 작성한 횟수만큼 모델에 이미지가 전달되므로, 여러 질문에서 사용할 이미지는 state에 한 번만 설정하고, 각 질문에서 경로로 참조하면 토큰을 절약할 수 있습니다.
이미지는 입력 토큰으로 계산되며, 단가는 텍스트와 동일합니다.
이미지 전용 추가 요금은 없지만, 장당 토큰 수를 추정하는 방법은 아직 문서에 나와 있지 않습니다.
지원 형식은 PNG와 JPEG의 정지 이미지입니다.
참고로, 이미지와 Box는 아직 프로토타입 용이라는 위치 지적입니다. 요청 형식이나 제한, 정확도는 릴리스마다 변경될 수 있습니다.
실험 내용
이번에는 알려진 사진과의 비교, 문장으로의 분류, 이미지 예시를 통한 분류, 프레임 간 변화, 물체의 위치 찾기 5가지를 시도합니다.
확대 이미지를 통한 재판정, 타일 분할을 통한 탐색, Score, Jev 1.13은 제외했습니다.
비교 상대는 OpenAI의 Decisions API입니다.
이미지는 사용자 메시지의 input_image에 data URL로 설정했습니다.
질문 유형은 predicate, choice, score의 세 가지입니다. predicate가 Jev의 Noul에 해당합니다.
선택지는 문장으로 정의하며, 위치를 반환하는 질문 유형은 없습니다.
양쪽에 보낸 것은 다음 10문제였습니다.
테이블
| 케이스 | Jev로 설정한 파라미터 | 질문 유형 | 정답 |
|---|---|---|
| 같은 개 | 발견된 개는 state , 게시 사진은 instructions |
| Noul | 같은 |
| 다른 개 | state의 개만 별개체로 교체 | Noul | 다르 |
| 현관의 상자, 봉지, 맨손 | 사진은 state , 기준은 문장 | Choice | package、bag、nothing |
| 제스처 | 대상은 state , 예는 criteria |
| Choice | thumbs_up |
| 문이 열렸는지 | 3장을 state의 배열로 |
Noul | 열렸다 |
| 머그컵이 있는지 | 주방 사진을 state |
| Noul | 있다 |
| 무손상, 금 간 제품 | 사진을 state |
| Noul | 손상 없음, 손상 있음 |
Box를 이용한 위치 감지는 기사 후반부에서 별도로 검증합니다.
Yes/No 질문은 확률 0.5 이상을 '예'로 하여 정답과 대조했습니다.
Choice는 반환된 값이 정답 레이블과 일치하면 정답입니다.
질문의 의미는 양쪽 API에서 통일했지만, 이미지 참조 방식에 맞춰 문구를 변경했습니다.
영어로 작성한 것은 Jev 모델의 문서에서 현재 영어의 정확도가 가장 높다고 알려져 있기 때문입니다.
대기 시간은 요청 전송 시작부터 응답 수신 완료까지입니다. 이미지 업로드 시간도 포함합니다.
비용은 공표 단가에 응답의 input_tokens를 곱하여 계산했습니다. 실제 청구액과는 대조하지 않았습니다.
사진은 모두 생성한 것이며, 눈으로 보면 정답을 알 수 있도록 했습니다.
손상 판정 2장은 Decisions API 문서에 있는 제품 사진 예시를 참고했습니다.
환경
모델 목록에서는 jev-latest가 jev-1.13.0을, jev-preview가 jev-1.14.0를 가리키고 있었기 때문에, 이번에는 jev-1.14.0를 직접 지정했습니다.
Jev에 요청 보내기
문장 기준으로 현관 사진 분류하기
현관 카메라 사진을 state로 설정하고, 무엇을 가지고 있는지 Choice로 물었습니다.
선택지는 문장으로 정의합니다.
doorbell-request.json
{
"model": "jev-1.14.0",
"state": {"door": "door"},
...
사진은 골판지 상자, 종이 봉지, 맨손의 3장입니다.
맨손 사진에서는 보이는 손은 비어 있고, 다른 한쪽 손을 몸 뒤로 감추고 있습니다.
정답은 각각 package,
bag,
nothing입니다.
같은 개인지 확인하기
발견된 개의 사진을 state로 설정하고, 길 잃은 개의 게시 사진을 instructions에서 참조합니다.
다른 개를 판정하는 케이스에서는, state의 사진만 검은 개로 교체했습니다.
제스처 분류하기
판정 대상 손을 state에, 각 제스처의 예시를 criteria에 설정했습니다.
gesture-criteria.json
{
"state": {"camera": "camera"},
"questions": {
...
thumb와 같은 문자열은 assets의 키입니다.
판정 대상도 엄지손가락을 치켜세우고 있지만, 예시 사진과는 각도를 다르게 했습니다.
문서에서는 참조 문자열에 UUID를 사용하는 것을 권장합니다.
cat처럼 짧은 문자열인 경우, category 안에도 일치할 수 있기 때문입니다.
이번 실험에서는 짧은 키를 사용했습니다.
판정 대상 사진입니다.
선택지 예시로 보낸 사진입니다.
문 변화 보기
같은 문을 찍은 3장을 오래된 순서대로 state의 배열에 넣고, 이 사이에 문이 열렸는지 Noul로 물었습니다.
제품 손상 판정하기
제품 자체에 보이는 손상이 있는지 Noul에게 물어보았습니다.
그림자나 포장의 흠집은 제외하도록 지시했습니다.
Decisions API로 요청 보내기
Decisions API에는 현관 사진을 다음과 같이 보냈습니다.
Jev의 criteria에 작성한 문장은 choices의 description에 설정합니다.
decisions-doorbell.json
{
"model": "gpt-6-luna",
"input": [{
...
선택지를 이미지로 정의하는 매개변수는 없습니다.
그래서 제스처 판정 대상과 이미지 예시에 레이블을 붙여 같은 사용자 메시지에 나열했습니다.
강아지 게시 사진과 문 3장도 하나의 메시지로 묶었습니다.
정확도
| 케이스 | 정답 | Jev | Decisions API |
|---|
| 같은 강아지 | 같음 | 0.93 | 0.99 |
| ... | | | |
| 10문제 모두 양쪽에서 정답이었습니다. | | | |
육안으로도 판별하기 쉬운 사진을 사용했기 때문에, 여기는 예상대로입니다.
차이가 난 것은 확률 값입니다.
Decisions API는 0.99, 1.00, 0.00처럼 0 또는 1에 가까운 값을 반환하는 경향이 있었습니다.
반면, Jev는 같은 강아지에서 0.93, 문에서 0.92, 머그컵에서 0.95입니다.
제스처는 반대였고, Jev가 confidence 1.00이었던 것에 비해 Decisions API는 fist에 0.04를 남겼습니다.
어느 쪽 모두 판정 기준인 0.5에서 벗어나지 않았으며, 결과가 경계 근처가 된 경우는 없었습니다.
손을 비운 사진에서는 한 손을 몸 뒤로 돌리고 있지만, 두 API 모두 nothing이라고 답했습니다.
정확도의 차이를 알아보려면 더 판별하기 어려운 사진이 필요합니다.
속도
| 케이스 | Jev 대기 시간[초] | Decisions API 대기 시간[초] |
|---|
| 같은 강아지 | 0.383 | 1.214 |
| ... | | |
| 합계는 Jev가 3.639초, Decisions API가 6.269초였습니다. | | |
10문제 중 9문제에서 Jev의 대기 시간이 짧았고, Decisions API가 짧았던 경우는 머그컵 유무뿐이었습니다. 차이는 0.034초였습니다.
다만, 이 대기 시간에는 이미지 업로드가 포함되어 있습니다.
Jev는 multipart로 파일을 보내고, Decisions API는 base64로 JSON에 임베드하기 때문에 전송하는 데이터량도 다릅니다.
Decisions API의 응답에는 처리 시간을 나타내는 openai-processing-ms 헤더가 포함됩니다.
| 케이스 | openai-processing-ms |
|---|---|---|
| 같은 강아지 | 836 |
| ... |
중앙값은 315ms로, 모든 케이스에서 실측한 대기 시간보다 짧았습니다.
예를 들어 같은 강아지 케이스는 대기 시간 1.214초에 비해 처리 시간은 836ms였습니다.
대기 시간에는 API 측의 처리가 아닌 이미지 전송이나 응답 수신도 포함됩니다.
측정은 각 1회이므로, 0.03초 정도의 차이는 측정마다 바뀔 가능성이 있습니다.
다만, 이번에는 10문제 중 9문제에서 Jev가 더 짧은 결과였습니다.
비용
공표 단가는 입력 100만 토큰당 Jev가 0.042달러, Decisions API가 0.10달러입니다.
출력 토큰은 둘 다 과금되지 않습니다.
아래 표의 비용은 응답의 input_tokens에 공표 단가를 곱하여 산출했습니다.
| 케이스 | Jev 토큰 | Decisions API 토큰 | Jev 비용[달러] | Decisions API 비용[달러] |
|---|---|---|
| 같은 강아지 | 6752 | 2602 | 0.00028358 | 0.0002602 |
| ... |
금액이 작아 표만으로는 비교하기 어려워 막대 그래프로 만들었습니다.
우선은 10문제의 합계입니다.
케이스별로 나열하면 다음과 같습니다.
10문제의 합계는, Jev가 약 0.4센트, Decisions API가 약 0.26센트입니다.
이번 건수에서는 작은 차이지만, 호출 횟수가 늘어나면 토큰 수의 차이가 비용에 반영됩니다.
이미지 매수나 참조 횟수는 실제 용도에 맞춰 조정할 필요가 있습니다.
물건의 위치 찾기 (Box)
Box가 반환하는 범위를 8장의 사진으로 확인했습니다.
대상은 주방 컵, 골판지 상자, 종이 가방, 개, 게시 사진, 손, 열린 문, 금 간 컵입니다.
이미지는 state.photo에 설정하고, Box의 instructions에서 대상을 지정했습니다.
예를 들어, 주방 컵에는 the coffee mug in photo, 골판지 상자에는 the cardboard box in photo와 같이 지정했습니다.
이번에는 정답 영역을 수동으로 표시하지 않았기 때문에 IoU 등의 수치로는 평가하지 않았습니다.
반환된 영역으로 이미지를 잘라내어 지정한 대상이 포함되어 있는지 육안으로 확인합니다.
각 좌표는 이미지의 너비와 높이에 대한 비율입니다.
| 대상 | top | bottom | left | right | confidence | 대기 시간[초] | 토큰 |
|---|
| 주방 컵 | 0.42 | 0.88 | 0.45 | 0.83 | 0.91 | 0.293 | 6724 |
| ... | | | | | | | |
| 여기부터는 반환된 영역으로 잘라낸 이미지를 순서대로 보겠습니다. | | | | | | | |
주방 컵은 본체와 손잡이가 깔끔하게 들어왔습니다.
골판지 상자는 범위가 다소 커서 몸통까지 포함되어 있습니다.
종이 가방은 이 역시 범위가 다소 크고, 가방 내용물 범위까지 잘라냈습니다.
개는 귀부터 앞발까지 들어왔습니다.
게시된 인쇄 사진에는 핀과 주변 코르크도 약간 포함되었습니다.
손은 엄지손가락과 잡은 손가락까지 들어가고, 손목이 영역의 하단에서 잘렸습니다.
confidence는 0.52로, 8건 중 가장 낮은 값이었습니다.
열린 문에는 판자와 손잡이가 들어가 있고, 복도는 거의 포함되어 있지 않습니다.
금 간 컵에는 깨진 테두리와 손잡이가 들어 있습니다.
지정한 대상은 8장 모두 영역 안에 있었습니다.
일단 범위 내에는 있지만, 영역을 정확히 맞추는 정도의 정밀도는 나온 것 같지 않습니다.
손도 대상 전체가 들어가 있지만, confidence는 다른 7건보다 낮은 0.52였습니다.
요약
Jev에서는 이미지를 state,
instructions,
criteria에 설정할 수 있습니다.
이미지 예시를 통한 선택지 정의나 Box에 의한 위치 감지는 Decisions API에는 없는 기능입니다.
이번 10문제에서 두 API 모두 만점이었고, 전 문항을 정답으로 맞혔습니다.
대기 시간은 Jev가, 비용은 Decisions API 쪽이 더 작은 결과였습니다.
정확도의 차이는 판별하기 더 어려운 사진을 준비해서 다시 조사해보고 싶습니다.
참고
토론