[도입 무산] CPU ‐ GPU 이미지와 태스크 결과 전송 구현 - 100-hours-a-week/5-yeosa-wiki GitHub Wiki
*아래 내용은 cpu 로딩 및 디코딩 후 gpu에 이미지 전송하는 방안을 도입 계획하였으나, 실제 gpu에서 로딩 및 디코딩하는 것으로 결정되어 무산됨. 다만, 도입 테스트를 위해 구현했었던 내용이여서 아카이빙을 위해 남겨둠.
1. 구현해야 할 것
a. 세팅 관련
- gpu url을 .env에 저장해두기
- cpu main.py에서 gpu client 등록해두기
b. 임베딩 요청
-
임베딩은 요청을 cpu 서버에서 받아서 이미지 디코딩까지 한 다음에 client 통해 gpu 서버에 임베딩 요청 보내기
- 요청 보낼 때, list[np.ndarray]를 피클링
- 요청 보낼 때, 이미지명과 디코딩한 것을 모두 보내야 함
{ "images": ["img1.jpg", "img2.jpg"], "data": [ndarray1, ndarray2] }
아래와 같은 형식을 이용하지 않은 이유는 루트 dict 파싱에서 걸리는 약간의 오버헤드도 없게 하기 위해서
-
루트 딕셔너리 구조
{ "images": [ {"filename": "img1.jpg", "data": np.ndarray(...)}, {"filename": "img2.jpg", "data": np.ndarray(...)}, ] }
-
json으로 body 보낼 수 없는 이유
json.dumps는 파이썬 표준 객체(
list
,dict
,int
,float
,str
,bool
,None
)만 직렬화 가능하다.바이너리 직렬화 후, 전송해야 한다.
-
요청을 전체 dict 형태로 감싸지 않은 이유
왜 리스트 형태가 더 적합한가?
1. pickle 기반 직렬화에서는 루트 타입이 중요하지 않다
JSON
기반 API라면 루트가 무조건dict
여야 하나,pickle
은list
,dict
,tuple
,set
등 어떤 Python 객체든 그대로 직렬화 가능- → 루트가 리스트여도 전혀 문제 없음
2. GPU 서버에서 바로 for 루프 돌리기 쉬움
for item in image_items: # image_items == List[Dict[filename, data]] ...
- 루트가 리스트면 바로 순회 처리 가능
- 루트가 딕셔너리면
image_items["images"]
등 키 접근 후 별도 단계 필요
-
이미지명과 디코딩을 별개의 리스트로 보낸 이유
이미지 로딩 및 디코딩 결과인 ‘디코딩된 이미지’는 배열 형태로 반환됨. 그리고 임베딩에서도 이미지명과 디코딩된 이미지를 배열 형태로 이용함. 그렇기 때문에 요청을 보내는 쪽과 받는 쪽 모두 ’이미지명 배열과 디코딩 결과 배열’ 방식이 중복 작업 없이 효율적이다.
-
gpu 서버에서 임베딩 작업
- 요청을 받을 때, pydantic을 이용하지 않는다. json 기반 요청/응답일 경우, pydantic 모델이 사용되지만 여기서는 np.ndarray를 넘기기 위해서 피클링 방식을 이용하기 때문에 pydantic을 이용하지 않는다.
-
응답(이미지명, 임베딩 값) 받아서
{ "message": "success", "data": { "img1.jpg": [...], "img2.jpg": [...], } }
- 유효하지 않은 응답이면 백엔드에 실패 반환
- 유효한 응답이면 언피클링 후, cpu 서버에서 캐싱
-
gpu 서버는 받은 요청을 언피클링해서 임베딩 작업 진행 임베딩 결과를 피클링해서 cpu 서버에 반환
- 받은 요청에는 파일명과 디코딩된 이미지가 포함되어 있고
- 반환 시에는 파일명과 임베딩 결과를 반환해야 한다.