[AWS S3] boto3를 이용해서 numpy array를 s3에 업로드, 다운로드 하기

0

추출한 얼굴 임베딩 numpy array를 S3에 업로드하고, 필요할 때 다운로드해서 사용해야 하는 상황이다.

참고로, 로컬에 다운로드되는 방식을 피하기 위해 boto3의 upload_fileobjdownload_fileobj 함수를 사용했다.


1. 문제 상황

기존에 numpy array 데이터를 문자열로 바꿔서 인코딩을 진행한 후, BytesIO 객체로 만들어서 S3에 업로드 하였고,

	'''S3에 데이터 업로드 하는 코드'''
    embedding : numpy array 형식의 데이터 
    str_embedding = np.array2string(embedding)
    byte_embedding = io.BytesIO(str_embedding.encode())
    s3 = boto3.client('s3')
    s3.upload_fileobj(byte_embedding, '버킷 이름', "객체 이름")

아래와 같이 가져오려고 코드를 작성했지만 바이트 객체가 제대로 된 numpy array로 변환되지 못하는 문제가 있었다.

	'''S3에서 데이터 가져오는 코드'''
    f = io.BytesIO()
    s3.download_fileobj("버킷 이름", "객체이름", f)
    f.seek(0)
    embedding = np.frombuffer(f.read(), dtype=np.float32)

2. 해결 방안

s3에서 데이터 가져오는 코드를 그대로 사용하기 위해 아래와 같이 s3에 데이터 업로드 하는 코드를 수정했고, 제대로 동작하는 것을 확인할 수 있었다.

	'''S3에 데이터 업로드 하는 코드'''
    embedding : numpy array 형식의 데이터 
	byte_embedding = io.BytesIO(embedding.tobytes())
    s3 = boto3.client('s3')
    s3.upload_fileobj(byte_embedding, '버킷 이름', "객체 이름")

3. 결론

S3에 업로드할 때는 numpy의 tobytes() 함수를, 다운로드할 때는 frombuffer() 함수를 사용하자 !

	'''S3에 데이터 업로드 하는 코드'''
    embedding : numpy array 형식의 데이터 
	byte_embedding = io.BytesIO(embedding.tobytes())
    s3 = boto3.client('s3')
    s3.upload_fileobj(byte_embedding, '버킷 이름', "객체 이름")
	'''S3에서 데이터 가져오는 코드'''
    f = io.BytesIO()
    s3.download_fileobj("버킷 이름", "객체이름", f)
    f.seek(0)
    embedding = np.frombuffer(f.read(), dtype=np.float32)
profile
재미있는 아이디어 떠올리는 것을 좋아하고, 이를 구현하여 세상에 즐거움을 선물하고 싶은 사람입니다.

0개의 댓글