본문 바로가기
fastAPI

django & FastAPI 연결 과정 및 AI 모델 선정 과정

by shinminkyoung 2025. 7. 13.

#1. 프로젝트 소개 

프로젝트 진행 과정 중, AI 팀원이 따로 없어 백엔드를 맡은 필자가 AI 레포를 따로 만들어 

기존 백엔드(django)와 AI(FastAPI)를 연동했다.

 

상용화된 LLM 모델(예. GPT / Gemini)를 사용하지 않은 이유는, AI가 해야 하는 역할이 다음과 같기 때문이다.

프로젝트에서 AI 모델이 분석해야 하는 것

1. 사진의 배경 장소 구분 (이 사진은 경복궁에서 찍은 사진인가? 한강에서 찍은 사진인가? 에 대한 판단)

2. 사진 속 인물의 포즈 구분 (사진 속 인물은 어떠한 포즈를 하고 있는가? 브이? 하트?)

3. 기타 조건 들..

 

이 조건을 만족해야했다. 

유저가 사진을 찍거나 불러와 그에 대한 판단을 하는 것이 이 프로젝트의 주요 기능이다.

그러나, GPT나 Gemini에게 사진 자체를 넘겨 위 조건들에 대한 판단을 맡기기엔 비용 문제가 있었다.

 

고로, 오픈소스로 공개된 AI 모델을 자체적으로 구동하여 모델의 응답 값을 튜닝 해 기능을 구현하기로 했다. 

 

#2. 모델 선정 과정

현 시점 (7/13) 선정한 모델은 CLIP와 Media PIPE 두 개의 모델이다.

 

CLIP은 Open AI에서 개발한 텍스트-이미지 멀티 모달 모델로, 장소 판단을 위해 선정했다.

비슷한 모델로 BLIP/BLIP-2 모델이 있었지만, 모델 자체가 매우 무겁고, GPU 없이는 원활한 구동이 되지 않을 것이라 판단했다. 

(성능 자체는 BLIP/BLIP-2이 더 좋다고 한다.)

 

Media PIPE는 구글에서 개발한 모델로, 포즈 판단을 위해 선정했다.

표정 감지, Face mesh 등 다양한 기능을 제공하는데,

이 프로젝트에서는 "Pose"를 통해 손 부분을 크롭하고 -> "hands"를 통해 그 모양을 구분했다.

 

#3 모델 구현 과정

내가 사용한 두 모델은 이미 학습이 완료된 상태의 AI이기에 추가 학습 없이 레그를 띄워 기능을 구현했다.

 

(개발환경: Pycharm / FastAPI)

## 디렉토리 구조 

1. 장소 판단 관련 폴더 

-> location

2. 손 포즈 판단 관련 폴더

-> hands

Deulsseokz_AI/
├── hands/
│   ├── __init__.py
│   ├── detector.py
│   ├── pose.py
│   ├── utils.py
│   └── main.py
│
├── location/               
│   ├── __init__.py
│   ├── clip_model.py               ◀︎ CLIP 로딩 및 예측 함수
│   └── analyze.py                  ◀︎ FastAPI 경로 처리용

 

다음과 같이 정리할 수 있다.

 

구현 코드는 깃허브 레포지터리에서 확인할 수 있다.

공식 문서를 활용해 개발

https://github.com/openai/CLIP?tab=readme-ov-file 

 

#3-1. 모델 튜닝 중 트러블 슈팅

CLIP 모델의 장소 판단 기준 및 과정은 다음과 같다.

 

1. 사전학습 (Pretrained on large-scale image-text pairs) CLIP은 OpenAI에서 4억 쌍 이상의 이미지-텍스트 쌍으로 사전학습됨. 예: 이미지 = 에펠탑 사진 / 텍스트 = "Eiffel Tower" 이런 식의 쌍을 수백만 개 학습함.

 

2. 이미지와 텍스트를 같은 임베딩 공간으로 매핑 입력 이미지

    → Vision Transformer 또는 ResNet

    → 이미지 임베딩 생성 입력 텍스트

    → Transformer 기반 텍스트 인코더

    → 텍스트 임베딩 생성 이 두 임베딩을 비교하여 유사도(similarity)를 측정

 

3. 장소 판단 예를 들어 후보 텍스트: ["N서울타워", "광화문", "경복궁"] 입력 이미지와 각 텍스트의 임베딩 간 코사인 유사도를 계산 유사도가 가장 높은 텍스트를 예측 결과로 반환

 

후보 텍스트 입력을 초기에는,

candidates = ["N서울타워", "광화문", "롯데타워", "한강공원", "경복궁"]

 

다음과 같이 한국어로 작성했다. 정확도가 낮아 위와 같은 판단 기준을 고려해 장소명을 영어로 바꾸었다.

 

candidates = ["N Seoul Tower", "Gyeongbokgung Palace", "Han River Park"]

 

그 결과 정확도가 매우 향상되었다.

 

정확도 99% !!

 

 

#4. django 모델과 연동

AI 모델 서버를 먼저 돌린 후, 장고 모델 서버를 돌린 후 요청 및 반환을 통해 결과 값을 전달받았다.

이 또한 깃허브 레포에서 코드 확인..

 

과정은 다음과 같다.

[사용자 업로드 이미지]
		↓
[ Django View (REST API) ]
		↓
[ MediaPipe 판단: 포즈 추출 → 손 방향 계산 ]
		↓
[ CLIP 판단: 장소 유사도 판단 ("남산타워" 등) ]
		↓
[ 조건 만족 여부 → JSON 응답 ]

 

기존 데이터베이스에 저장된 조건 정보 (ex. [Han River Park] 한강에서 사진을 찍습니다.)에서 키워드를 추출해, 모델이 반환한 값을 비교해 도전의 성공 여부를 비교해야 한다.

 

#5. 테스트

테스트 이미지 (한강에서 브이하고 있는 사진)

 

1. 장소 판단

 

2. 포즈 판단

 

3. 장고 연결 결과값

{
    "isSuccess": true,
    "code": "COMMON200",
    "message": "성공입니다.",
    "result": {
        "pose_analysis": {
            "results": [
                {
                    "pose": "V sign",
                    "fingers": {
                        "index": true,
                        "middle": true,
                        "ring": false,
                        "pinky": false
                    }
                }
            ]
        },
        "location_prediction": {
            "location": "Han River Park",
            "confidence": 0.6373350024223328
        }
    }
}

 

 

아직 기능 구현을 완성한 게 아니라, 모델 연동만 한 값이라 응답이 오히려 직관적이다..

이제 구현하러 가야지