분류 전체보기 250

데이터 관리 패턴

데이터는 중앙화된 방식과 분산 방식 이렇게 2가지 방법으로 관리할 수가 있다. 1. 중앙 데이터 관리 중앙 데이터 관리 (centralized data management) 방식은 전통적인 데이터 중심 애플리케이션에서 가장 자주 사용하는 방식이었다. 모든 데이터를 단일 중앙 집중형 데이터베이스에 저장하는 방식으로 데이터를 저장 및 처리하도록 하는 것이다. 이 방식은 DB의 정규화가 가능하며, 아주 높은 데이터 일관성을 제공하는 등의 장점이 있다. 여러 컴포넌트가 데이터베이스의 모든 테이블에 접근할 수 있기 때문에 중앙 데이터 스토어가 여러 테이블에 데이터를 빠르게 저장하고 가져올 수 있다. 반면, 데이터베이스와 애플리케이션들 간에 강한 연관성이 생기게 되기에 Cloud-Native하지 못한 방법으로 취급..

다중 컨테이너 배포 패턴

마이크로서비스 아키텍처나 Auto-Scaling, 그리고 컨테이너 기술이 발전하면서 컨테이너 배포 패턴 자체도 다양한 방법론들이 나오게 되었다. 1. 사이드카 패턴 (Sidecar pattern) 다양한 기능을 추가 및 강화하기 위해 Pod 내에 추가적인 컨테이너를 추가하는 기법 2. 앰버서더 패턴 (Ambassador pattern) 사이드카 패턴의 세부 패턴 메인 컨테이너의 프록시 역할을 해주는 서브 컨테이너를 추가하는 패턴 nginx 등을 통해 프록시를 옆에 두는 패턴부터 REST API와 gRPC 사이의 컨버터 역할을 해주는 컨테이너 등 다양한 기법 존재 3. 어댑터 패턴 (Adaptor pattern) 사이드카 패턴의 세부 패턴 메인 컨테이너의 output 값이나 형태를 변형하는 컨테이너를 추가..

Container 2023.12.25

Subdomain에 대해 쿠키 공유하도록 설정하기

웹 서비스를 개발하다보면 상태 관리를 위해 세션이나 쿠키를 많이 사용하게 된다. 그렇게 서비스가 커지다보면 서브도메인이 많이 생기게 되는데, 모든 서브도메인에서 공통으로 가지는 상태가 생기게 될 것이고, 이를 처리하기 위해 쿠키를 서브도메인들 전체에 대해 공유하도록 만들어야 하는 상황이 발생하게 된다. 각 서브도메인 서비스마다 cookie getter와 setter API를 일일히 만드는 방법도 있겠지만, 서비스의 수가 많아지다보면 일일히 관리하기 어려워지게 되고, 시나리오가 더 복잡해지게 될 것이다. 그렇다면 도메인과 서브도메인 전부에 쿠키를 공유시키는 가장 간단한 방법은 무엇이 있을까? 답은 HTTP 쿠키에 대한 RFC 문서에 있다: https://datatracker.ietf.org/doc/html..

Web 2023.12.19

Request가 실질적으로 처리되기까지의 여정

백엔드에 요청을 보낼 때 대부분의 경우 요청의 처리 측면에 집중하는데, 이는 실제로는 마지막 단계에 불과하다. 요청이 처리될 준비가 되기까지 훨씬 더 많은 일이 일어나게 된다. 이를 6단계로 나누면 각 단계는 이론적으로 전용 스레드나 프로세스에 의해 실행될 수 있다. 거의 모든 백엔드, 웹 서버, 프록시, 프레임워크, 심지어 데이터베이스도 이 모든 단계를 수행해야 하며, 각 단계마다 다른 방식으로 수행한다. 1. Accept 요청은 종종 연결(TCP/QUIC)을 통해 전송되며 백엔드에서 연결을 수락해야 한다. 클라이언트가 포트 443에서 서버에 연결하면 서버 OS 커널에 의해 3방향 핸드셰이크가 완료되고 연결이 수신기 대기열에 배치되게 되는데, 이 대기열을 수락 대기열(accept queue)이라고 부른..

DevOps/백엔드 2023.10.31

텐서에서 Top-K 결과를 받아오는 방법

최근 RAG(Retrieval Augmented Generation)과 같은 반환 기반의 솔루션들이 많이 사용되면서 정보 반환의 중요성이 더 강조되어지고 있다. 물론 벡터 데이터베이스 등의 다른 솔루션을 사용해서 문제를 해결할 수도 있으나, 상황에 따라 상위 K개의 결과를 반환하는 알고리즘 및 기능을 직접 구현해야 하기도 할 것이다. FAISS나 ChromaDB도 좋은 툴이지만, 개인적으로는 torch.topk() 메소드를 사용하는 유사도 반환 방식 역시 알아둘 필요가 있다고 본다. 가장 큰 이유는, FAISS나 ChromaDB 등의 솔루션의 경우에는 상당한 양의 메모리를 소모한다. 더 빠른 결과의 반환을 위해 인덱싱을 하다보니 그만큼 많은 메모리를 사용하게 된다. 이는 다시 말해, 물리적 한계로 인해 ..

AI/PyTorch 2023.10.26

Transformers Decoder의 "past_key_values"에 대하여

허깅페이스 Transformers를 통해 생성 모델을 사용하다보면 생성 결과 자료구조 내에 "past_key_values"라는 값이 있는 것을 확인할 수 있다. 이를 보면 아마 두가지 의문점이 들 것이다: 1) 왜 과거의 key, value 값들이 중요한가 2) 왜 query는 포함되지 않는가? 이에 대해서 자세히 알아보기 위해서는 Transformer Decoder의 Causal Masking Self Attention에 대해서 알아야 한다. 기본적으로, transformer는 모든 단어를 병렬적으로 처리하기 때문에 autoregressive 한 특성이 없다. 따라서, Causal Masking을 사용해서 목표하는 문장의 일부를 가려서 인위적으로 연속성을 학습하게 한다. Vanilla Transform..

AI/Transformers 2023.10.26

Multi-Query Attention 설명

효율적인 Inference 요약, 질의응답(Q&A), 검색 증강 생성 등 언어 작업에 효과적인 기술로 Transformer 아키텍처에 기반한 대규모 언어 모델(LLM)이 부상했다. 하지만 이러한 모델을 사용하려면 계산 비용이 매우 많이 들며, 주로 NVIDIA GPU와 같은 컴퓨팅 가속기를 통해 실행된다. LLM에 대한 입력과 출력은 토큰 시퀀스(예: 단어)로 표현됩니다. 긴 시퀀스(즉, 컨텍스트 창이 긴)를 처리할 수 있는 LLM을 훈련하거나 미세 조정하는 것은 활발히 발전하고 있는 분야이다. 대부분의 OSS LLM 기본 모델은 2K 컨텍스트 창으로 사전 학습된다. 문서 요약이나 컨텍스트 기반 질문 답변과 같이 점점 더 많은 사용 사례에서 LLM이 처리하는 시퀀스 길이는 수천에서 수만 개의 토큰으로 상..

AI/LLM 2023.10.25

AWS SQS 톺아보기

Queue는 일반적으로 각 어플리케이션들이 가지는 Coupling을 끊어주는 역할을 한다. 프로듀서가 메시지를 보내서 Queue에 메시지를 저장하고, 이를 컨슈머가 가져가서 프로세싱 하는 방식이다. 위 그림은 일반적인 Queue 의 처리 과정이다. Producer 는 메시지를 생성하여 Queue로 메시지를 전송한다. Queue는 메시지를 일정 기간 가지고 있게 된다. Consumer 는 주기적으로 Queue를 Polling 하면서 신규 메시지가 있다면 가져가서 처리한다. 처리가 끝나면 Queue로 Ack 를 전송한다. (메시지 아이디에 해당하는 Ack를 받으면 Queue에서 메시지를 제거한다. ) 이렇게 프로듀서와 컨슈머를 Queue 라는 미들웨어로 분리하면, 각 시스템에 영향을 받지 않고 원하는 작업을..

AWS 2023.10.25

도커 리소스 사용량 제한

도커는 리눅스 커널이 기본으로 제공하는 기본 cgroup 기술을 이용해 애플리케이션이 좀 더 적은 리소스를 사용하게 할 수 있다. 쿠버네티스도 이러한 기능을 활용해 각 파드에서 사용하는 리소스의 양을 제한할 수 있다. 메모리 리소스 제한 컨테이너 내에서 애플리케이션을 실행할 경우 얻을 수 있는 주요 이점 중 하나는 바로 리소스 사용률을 제한할 수 있다는 것이다. 따라서 여러 애플리케이션이 동일한 하드웨어에 공존할 수 있으며 공정한 사용을 보장해준다. 200MB의 메모리와 1GB의 스왑 공간으로 제한하려면 docker run 명령어와 함께 --memory 및 --memory-swap 플래그를 사용할 수 있다. docker run -d --name mycontainer --publish 8080:8080 \..

Container/Docker 2023.10.25

컨테이너 이미지 빌드 시 최적화 및 보안

이미지 크기 최적화 대용량의 컨테이너 이미지를 사용하기 시작하면 몇 가지 문제에 직면하게 된다. 가장 먼저 기억해야 할 사항은 시스템의 하위 계층에서 제거된 파일이 실제 이미지에서 존재한다는 점이다. 다음 상황을 고려해보자. - A 계층 (이름이 BigFile인 대용량 파일 포함) - B 계층 (이름이 BigFile인 대용량 파일 제거) - C 계층 (B 계층을 기반으로 정적 바이너리 제거) 위와 같은 상황에서는 BigFile이 더 이상 컨테이너 이미지 내에 존재하지 않는다고 생각할 것이다. 결과적으로 이미지를 실행할 경우, 해당 파일에는 더 이상 접근이 불가능하다. 그러나 실제로는 A 계층에 여전히 위치하고 있다. 즉, 더 이상 접근이 불가능한 파일임에도 전체 컨테이너 이미지의 크기에는 영향을 미치는 ..

Container 2023.10.25