TL;DR; N그램을 설명한 글입니다. LLM from Scratch - Part 1. Statistical Language Models[LLM 바닥부터 만들기 - 파트1. 통계적 언어 모델의 원리] 부담 없이 즐기며 배우는 LLM 입문 강의 🚀오픈이벤트 50%할인! (~5/17이후 가격이 인상됩니다.)www.honglab.aiN-gram의 아이디어는 1948년 Claude Shannon 의 정보이론 논문에서 시작되었습니다. 핵심은 단순합니다. "다음 글자를 이전 글자를 기반으로 예측할 수 있지 않을까?" 라는 아이디어였습니다. 이후 1980년대에 들어서며 컴퓨터 성능이 발전하였고, 이러한 통계 기반 언어 모델을 실제로 활용할 수 있는 환경이 만들어지기 시작하였습니다. 그렇게 N-gram은 음성 인식,..
최근에 입사한 회사에서 새로운 프로젝트를 도입하려 하였습니다. 기존의 단일 모듈 기반 controller - service - repository 구조가 아닌 멀티 모듈 구조로 도입하기로 결정하였습니다. 멀티 모듈로 결정한 이유는 역할별 책임을 분리하여 이후 변경 범위를 줄이고 유지보수를 용이하게 만들기 위함입니다. 또한 도메인과 인프라를 분리함으로써 구조적인 의존성을 조금 더 명확하게 관리할 수 있다고 여겨졌습니다.빌드 툴은 메이븐이 아닌 그레들로 결정하였습니다. 그레들로 결정한 이유는 확장성과 유지보수성 때문입니다. 특히 멀티 모듈 환경에서는 공통 설정 관리와 유연한 빌드 구성이 중요하다고 판단하였고, 이러한 부분에서 그레들이 조금 더 적합하다고 느껴졌습니다.그레들로 결정하고 보니 메이븐처럼 XML ..
만약 외부 API의 스펙이 변경된다면 어떻게 처리해야 할까요? 이 경우에도 skip을 해야 할까요, 아니면 retry를 해야 할까요?외부 API 장애라고 해서 모두 같은 방식으로 처리하면 안 됩니다. 예를 들어 특정 row의 값이 잘못되었거나 필수 데이터가 누락된 경우라면, 이는 개별 데이터 품질 문제로 보고 skip 처리를 고려할 수 있습니다. 반면 외부 API의 응답 구조가 변경된 경우는 다르게 봐야 합니다. 이는 단순히 특정 데이터 하나가 잘못된 것이 아니라, 배치가 기대하던 계약이나 제약 자체가 깨진 상황입니다. 이런 경우까지 skip해버리면 전체 데이터가 잘못 처리되거나, 문제를 늦게 발견할 수 있습니다. 또한 네트워크 타임아웃이나 5XX 오류처럼 일시적인 장애는 retry 대상이 될 수 있습니..
몇 일 전, 긴 공백기를 지나 새로운 회사에 입사하게 되었습니다. 다행히도 저를 불러주는 곳이 있었고, 그 기회를 잡게 되었습니다. 해당 회사는 주로 SI 프로젝트를 수행하지만, 자체 솔루션도 함께 운영하고 있는 것으로 보입니다. 아직 구체적으로 어떤 프로젝트에 투입될지는 정해지지 않았습니다. 사전에 코드를 간단히 살펴보던 중, 로그를 println()으로 출력하는 방식이 사용되고 있는 것을 확인했습니다. 감각적으로는 println()을 로깅 용도로 사용하는 것이 적절하지 않다는 것을 알고 있었고, 실제로도 사용하지 않고 있었습니다. 다만, 왜 사용하면 안 되는지에 대해서는 명확하게 정리되어 있지 않았습니다. 그래서 출근 전에, println()을 로그로 사용하는 것이 왜 적절하지 않은지에 대해 스스로 ..
지금까지 학습한 내용을 간단하게 정리해보면, offset은 broker에 저장된 메시지의 순서를 의미하고, consumer는 이 offset을 기준으로 메시지를 읽고 처리하게 됩니다.그리고 어디까지 처리했는지를 기록하는 과정을 offset commit이라고 합니다. 이 commit 방식에는 크게 두 가지가 존재합니다. 자동 commit은 일정 주기에 따라 offset을 자동으로 기록해주기 때문에 구현이 간단하다는 장점이 있습니다. 하지만 처리 완료 여부와 관계없이 offset이 기록되기 때문에, 메시지를 처리하는 도중 애플리케이션에 장애가 발생할 경우 문제가 발생할 수 있습니다. 이 경우 Kafka는 해당 메시지를 이미 처리된 것으로 인식하게 되고, consumer가 재시작되더라도 메시지는 다시 전달되지..
카프카의 설정은 진짜일까?? - offset(1)원래 시나리오대로면, producer를 전부 끝내고 나서 consumer를 학습하려고 하였지만 살짝 우회하기로 결정하였습니다. 그 이유가 뭐냐면 카프카의 주요 특징중 하나가 offset으로 알고 있습니다. 제b-programmer.tistory.com오랜만에 Kafka 관련 글을 작성하게 되었습니다. 이번 글에서는 offset commit에 대해 알아보려고 합니다. Kafka의 offset은 기본적으로 broker에 저장됩니다. 하지만 이 offset을 기준으로 어디까지 처리했는지 관리하는 주체는 consumer입니다. 그 이유는 broker와consumer의 역할이 다르기 때문입니다. broker는 메시지를 저장하고 전달하는 역할을 할 뿐, 우리 서비스의..
웹소켓과 MQ는 모두 데이터를 전달하는 통로라는 공통점을 가지고 있습니다. 겉보기에는 둘 다 어떤 큐를 통해 메시지를 주고받는 것처럼 느껴질 수 있습니다. 하지만 실제로는 사용하는 목적도 다르고, 시스템 안에서 맡는 역할도 다릅니다. 보통 웹소켓은 실시간성, MQ는 비동기 처리라고 설명합니다. 물론 틀린 말은 아닙니다. 다만 이렇게 이분법적으로 나누면 두 기술의 차이를 충분히 설명하기에는 다소 부족하다고 느껴졌습니다. 웹소켓도 결국 비동기적으로 동작하고, MQ 역시 상황에 따라 실시간에 가깝게 활용될 수 있기 때문입니다. 따라서 이 글에서는 단순한 특징 비교에 그치지 않고, 웹소켓과 MQ에서 말하는 "큐"를 각각 어떻게 이해해야 하는지에 초점을 맞춰 정리해보겠습니다.각각의 큐에는 어떤것을 전달 할까?간단..
Race condition은 여러 작업이 동시에 같은 데이터를 처리할 때, 실행 순서에 따라 결과가 달라지는 문제입니다.쉽게 말해, 같은 자원에 대한 접근이 동시에 발생하면서 기대한 결과와 실제 결과가 달라지는 상황입니다.이전 선착순 쿠폰 시스템을 개발할 때도 이러한 문제가 발생했습니다.예를 들어 100명의 사용자가 동시에 쿠폰 발급을 요청했다고 가정하겠습니다. 응답 결과만 보면 6건만 성공했고, 94건은 실패했습니다.그렇다면 정상적인 시스템이라면 실제 DB에도 성공한 6건만 저장되어 있어야 합니다.하지만 실제로 확인해보니 DB에는 96건의 쿠폰 발급 내역이 저장되어 있었습니다.즉, 애플리케이션이 사용자에게 반환한 결과와 실제 데이터베이스 상태가 서로 일치하지 않았습니다.이런 상황을 정합성이 깨졌다고 할..
배치의 전반적인 처리 과정에 대해 학습을 진행하였다. 배치는 기본적으로 3가지 단계로 동작한다.Reader → Processor → Writer데이터를 읽고, 가공하고, 저장하는 구조이다.하지만 현재까지는 이 흐름을 단순하게 확인하기 위해 배치를 강제로 실행시키는 방식으로 동작을 확인하고 있었다.즉, 배치의 구조를 제대로 사용하기보다는 동작 자체를 이해하는 데에 초점을 맞춘 상태였다. 하지만 스프링 배치에서는 이러한 작업 흐름을Job과 Step이라는 개념을 통해 구조적으로 관리할 수 있다. 단순 실행에서 벗어나, 실행 단위와 흐름을 명확하게 정의할 수 있는 것이다.그렇다면 스프링 배치에서는 이 Job과 Step을 어떻게 구성하고 사용하는지 확인해보자. 그리고 저번시간에 재대로 설명하지 않은 chunk도 ..
저번시간에 간단하게 배치가 어떤것인지 그리고 Reader에 대해 짧게 학습을 진행하였다. 간단하게 복습하면 Reader은 어딘가에 쌓여있는 데이터를 읽는 작업을 일컫는다. 하지만 배치의 전 과정을 생각해보면, 단순히 읽는 것으로 끝나지 않는다. 데이터를 읽고, 가공하고, 저장하는 흐름으로 이루어져 있다. 그렇다면, 어째서 이러한 과정을 거칠까? 이유는 생각보다 단순하다.첫 번째는 데이터의 크기 때문이다. 대량의 데이터를 한 번에 처리하려고 하면 메모리 부담이 커지고, 중간에 실패했을 때 다시 처음부터 실행해야 하는 문제가 발생한다. 그래서 배치는 데이터를 일정 단위로 나누어 끊어서 처리하는 방식을 선택한다.두 번째는 데이터의 구조가 서로 다르기 때문이다. 어딘가에 쌓여있는 데이터의 구조와 DB에 저장되어..
원래 시나리오대로면, producer를 전부 끝내고 나서 consumer를 학습하려고 하였지만 살짝 우회하기로 결정하였습니다. 그 이유가 뭐냐면 카프카의 주요 특징중 하나가 offset으로 알고 있습니다. 제가 알기로 offset은 카프카(브로커)에서 값을 읽을때 특정 부분까지 읽도록 하는걸로 알고 있습니다. 물론 이게 틀린내용일 수 도 있지만, 뭐 상관없습니다. 다시 제대로 학습하면 되는거니까요. 시작해봅시다.그래서 offset이 뭐냐면..offset은 메시지의 위치를 나타내는 번호입니다. kafkasms 메시지를 다음과 같이 저장합니다.[0] [1] [2] [3] [4] ...여기서 숫자가 바로 offset입니다. 즉, kafka는 메시지를 순서대로 쌓고, index처럼 offset을 붙입니다.또한,..