[도입 무산] 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여야 하나,
      • picklelist, 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 서버에 반환

    • 받은 요청에는 파일명과 디코딩된 이미지가 포함되어 있고
    • 반환 시에는 파일명과 임베딩 결과를 반환해야 한다.