FastAPI 파일 업로드, 대용량은 스트리밍과 임시파일로 처리하세요

FastAPI에서 UploadFile로 받은 파일은 일정 크기까지만 메모리에 머물다가, 그 이상은 자동으로 디스크의 임시파일로 넘어갑니다. FastAPI 파일 업로드 코드를 대용량 파일에 그대로 쓰면, 이 전환 시점과 임시파일 정리 시점을 모른 채 서버 메모리나 디스크를 순식간에 채우는 경우가 많습니다. 이 글에서는 스트리밍 방식으로 파일을 받아 임시파일로 안전하게 저장하는 실제 코드와, 이 방식이 통하지 않는 상황까지 함께 짚어드립니다. … Read more

pydantic v2 마이그레이션, 실제로 어디서 코드가 깨지는지 정리해봤습니다

pydantic 공식 마이그레이션 가이드에는 변경 항목이 20개 넘게 나열되어 있습니다. 그런데 실제로 서비스 코드를 pydantic v1에서 v2로 옮겨보면, 이 중 대부분은 타입 힌트만 스치고 지나가고 딱 몇 군데에서 에러가 집중적으로 터집니다. 이번 글에서는 그 몇 군데—Config 클래스, validator 데코레이터, dict()/json() 메서드, Optional 필드 기본값—를 실제 코드 예시로 짚어보고, 호환성을 지키면서 넘어가는 방법도 함께 정리해보겠습니다. 전제부터 … Read more

파이썬 GIL 때문에 안 빨라질 때, 스레드·프로세스·async 고르는 기준

결론부터 말씀드리면, 코드가 느린 이유가 CPU 연산 때문인지 I/O 대기 때문인지에 따라 정답이 완전히 갈립니다. CPU 연산이 병목이라면 스레드를 아무리 늘려도 파이썬 GIL이 한 번에 하나의 스레드만 바이트코드를 실행하도록 막고 있어서 속도가 그대로거나 오히려 떨어집니다. 반면 네트워크 요청이나 파일 입출력처럼 대기 시간이 긴 I/O 바운드 작업이라면 멀티스레드든 async든 GIL이 거의 걸림돌이 되지 않습니다. 이 글은 … Read more

Parquet CSV 전환 시점 판단법: 용량·읽기 속도·스키마

결론부터 말씀드리면, CSV 파일 하나의 용량이 커져서 열 때마다 버벅이거나 전체 컬럼 중 일부만 골라 쓰는 쿼리가 반복된다면 그때가 Parquet CSV 전환을 검토할 시점입니다. 컬럼 단위로 저장하는 구조 덕분에 용량은 눈에 띄게 줄고, 필요한 컬럼만 골라 읽는 작업에서는 읽기 속도 차이가 크게 벌어집니다. 다만 스키마가 자주 바뀌거나 작은 파일을 계속 append하는 로그성 파이프라인이라면 오히려 CSV … Read more

pandas merge 메모리 터짐 방지: 조인 전략과 category dtype

‘pandas merge 메모리’라는 키워드로 검색해서 들어오셨다면, 이미 merge() 한 줄 실행했다가 커널이 죽거나 스왑이 도는 상황을 겪으셨을 가능성이 큽니다. 결론부터 말씀드리면, 원인은 대개 두 가지입니다. 조인 방식(how, 조인 키 선택)이 결과 행 수를 불필요하게 부풀리고 있거나, 조인 키로 쓰는 문자열 컬럼이 object dtype이라 메모리를 과하게 먹고 있는 경우입니다. 이 글은 pandas 2.2 버전을 기준으로, 조인 … Read more

임베딩 차원 축소, 벡터 절반으로 줄여도 검색 품질 괜찮을까요

임베딩 차원 축소를 해서 벡터를 절반으로 잘라내도, MRL(Matryoshka Representation Learning) 방식으로 학습된 모델이라면 검색 품질 저하는 생각보다 크지 않은 경우가 많습니다. 다만 이 말은 아무 임베딩 모델에나 해당되는 이야기가 아니고, 모델이 애초에 그렇게 학습됐을 때만 성립합니다. 일반적인 방식으로 학습된 벡터를 그냥 절반으로 잘라내면 검색 품질이 급격히 무너지는 경우도 흔합니다. 이 글에서는 임베딩 차원 축소가 실제로 … Read more

임베딩 비용 줄이는 순서: 중복 제거→캐시→차원 축소

임베딩 비용을 줄이는 법이 궁금해서 검색하셨다면, 답은 순서에 있습니다. 무작정 더 저렴한 모델로 바꾸기 전에 중복 제거, 캐시, 차원 축소 순서로 손보면 같은 파이프라인에서도 서로 다른 지점의 비용이 줄어듭니다. 중복 제거와 캐시는 API 호출 자체(토큰 사용량)를 줄이고, 차원 축소는 벡터를 저장·검색하는 비용을 줄여서 손대는 대상이 다르기 때문입니다. 임베딩 비용은 왜 생각보다 빨리 늘어나나요? 임베딩 API … Read more

쿼리 재작성, 짧은 질문도 검색되게 만드는 법과 HyDE 비교

질문을 세 단어로 치면 검색 결과가 하나도 안 나오는데, 이유가 뭘까요? 벡터 검색기는 질문 문장 전체의 의미를 임베딩해서 찾는데, 단어 몇 개만 던지면 비교할 문맥이 부족해 관련 문서와의 유사도 점수가 낮게 나옵니다. 이럴 때 쓰는 방법이 쿼리 재작성이고, 그래도 리콜이 안 오르면 가상의 답변 문서를 먼저 만들어 검색하는 HyDE로 넘어갑니다. 두 방법 다 검색 품질을 … Read more

청크 오버랩으로 끊긴 문맥 살리기, 부모-자식 청크와 비교해보기

RAG로 챗봇을 만들어 놓고 나서, 분명 원본 문서에 정확한 답이 있는데도 챗봇이 엉뚱한 소리를 하는 경험 한 번쯤 해보셨을 겁니다. 검색된 조각을 열어보면 문장이 중간에서 뚝 끊겨 있고, 그 앞뒤 맥락이 통째로 날아간 경우가 많습니다. 이럴 때 가장 먼저 손볼 수 있는 값이 청크 오버랩이고, 그래도 부족하면 검색용 조각과 LLM에 넘길 조각을 아예 분리하는 부모 … Read more

RAG 권한 필터링, 검색 파이프라인 어디에 넣나

RAG(검색 증강 생성) 시스템에서 사용자마다 볼 수 있는 문서가 다르다면, 권한 필터링은 벡터 유사도 검색과 동시에 걸어야 합니다. 검색 결과를 다 받아온 뒤 나중에 걸러내는 방식은 결과 개수 부족과 정보 유출이라는 두 가지 문제를 동시에 안고 갑니다. 이 글에서는 벡터 DB 종류별로 메타데이터 필터를 어느 시점에 적용해야 하는지, 실제 코드와 함께 정리해 보겠습니다. 사내 문서, … Read more