로그인을 처리하는 방식에는 크게 세션 방식과 토큰 방식이 있습니다. 토큰 방식을 사용하는 대표적인 이유는 stateless하기 때문입니다. 여기서 stateless하다는 것은 서버가 로그인 상태를 직접 저장하지 않아도 된다는 뜻입니다. 즉, 사용자가 로그인한 뒤 요청을 보낼 때마다 토큰을 함께 전달하고, 서버는 그 토큰이 유효한지만 검증하면 됩니다. 토큰 방식의 장점은 트래픽이 많아졌을 때 조금 더 잘 드러납니다. 세션 방식은 로그인 상태를 서버나 세션 저장소에 보관해야 하기 때문에, 요청이 많아질수록 세션 조회 비용이 계속 발생합니다. 반면, 토큰 방식은 서버가 별도의 로그인 상태를 저장하지 않아도 되기 때문에, 많은 요청이 동시에 들어와도 상대적으로 서버 부담이 적을 수 있습니다. 물론 실제 서비스에..
한국어를 뉴럴 네트워크로 학습시킬 때는 몇 가지 어려움이 존재합니다. 대표적인 예가 조사입니다. 한국어에는 ‘가’, ‘는’, ‘이’와 같은 조사가 존재하며, 이들은 명사와 결합하면서 문장에서의 역할이나 의미를 바꿀 수 있습니다. 예를 들어 같은 명사라도 어떤 조사가 붙느냐에 따라 주어가 되기도 하고, 목적어나 비교 대상처럼 해석될 수도 있습니다. 따라서 단순히 공백 기준으로 문장을 나누면 단어의 의미나 문법적 역할을 정확하게 파악하기 어렵습니다. 이러한 문제를 해결하기 위해 형태소 분석을 사용할 수 있습니다. 형태소 분석을 통해 명사와 조사를 분리하면, 모델이 단어 자체의 의미와 문장 내 역할을 더 명확하게 학습할 수 있습니다.하지만, ChatGPT와 같은 현대적인 LLM은 형태소 분석을 사용하지 않습니..
현재 SI 프로젝트를 진행하고 있습니다. 프로젝트의 상세한 내용은 보안상 말씀드릴 수 없지만, 업무를 진행하면서 확인하고 싶은 기술적인 내용을 정리해보려고 합니다. 이번에 다루려는 주제는 프론트 화면에서 엑셀 파일을 업로드하면, 해당 데이터를 서버에서 읽어 DB에 저장하는 흐름입니다. 단순히 엑셀을 업로드하고 저장하는 기능처럼 보일 수 있지만, 실제로는 파일 파싱 방식, 데이터 검증, 대량 데이터 처리, 트랜잭션 범위, 실패 처리 방식 등 여러 가지 선택지가 존재합니다. 따라서 이번 글에서는 특정 실무 코드를 공개하기보다는, 예제 코드를 바탕으로 어떤 기술을 선택할 수 있는지, 그리고 그 선택에 어떤 트레이드오프가 있는지를 정리해보려고 합니다. 여기에 등장하는 코드는 실제 프로젝트 코드가 아니며, 개념 ..
기존 언어 모델 방식 중 하나인 N-gram은 이전 데이터를 기반으로 다음 단어를 예측하는 방식입니다. 하지만 N의 크기가 너무 낮다면 문맥을 충분히 이해하지 못해 의도를 알 수 없는 문장을 생성할 수 있습니다. 반대로 N의 크기가 너무 높아진다면 문맥 자체는 자연스러워지지만, 희소성 문제가 심해져 새로운 문장을 생성할 가능성이 낮아지게 됩니다. 이러한 한계를 해결하기 위해 다양한 연구가 진행되었고, 2003년 조수아 벤지오 교수의 신경망 기반 언어 모델 연구가 큰 전환점이 되었습니다. 특히 단어를 벡터로 표현하고 신경망을 통해 다음 단어를 예측하는 방식은 이후 현대 LLM의 기반이 되는 흐름으로 이어지게 됩니다. 이번 글에서는 이러한 흐름 속에서 등장한 뉴럴 네트워크가 무엇인지에 대해 알아보겠습니다.뉴..
외부 API에 접근하기 위해서는 HTTP 통신이 필요합니다. 직접 HTTP 통신 코드를 구현할 수도 있지만, Spring 환경에서는 WebClient, RestTemplate, FeignClient와 같은 HTTP 클라이언트 라이브러리를 사용할 수 있습니다. 그렇다면 어떤 라이브러리를 사용하는 것이 좋을까요?일단 내가 중요하다고 생각하는걸 생각해보자.기술을 선택할때 가장 먼저 고려해야 하는 요소는 환경입니다. 현재 어떤 프레임워크를 사용하고 있는지, 팀원들의 숙련도는 어느 정도인지, 현재 프로젝트 구조와 운영 방식은 어떠한지 등을 함께 고려할 필요가 있습니다.예를 들어 팀 전체가 RestTemplate에 익숙한 환경이라면, 무조건 최신 기술이라는 이유만으로 WebClient를 도입하는 것이 오히려 유지보..
N-gram 이해해보기TL;DR; N그램을 설명한 글입니다. LLM from Scratch - Part 1. Statistical Language Models[LLM 바닥부터 만들기 - 파트1. 통계적 언어 모델의 원리] 부담 없이 즐기며 배우는 LLM 입문 강의 🚀오픈이벤트 50%할인! (~5b-programmer.tistory.com이전에 국립국어사전 데이터를 기반으로 N-gram을 적용한 적이 있습니다. 당시에는 총 548,385개의 단어를 추출하였으며, 한 글자 단어, 속담, 관용구, 구 형태의 표현, 신조어 등은 제외하였습니다. N-gram을 간단히 설명하자면, 이전 데이터(문맥)를 기반으로 다음에 어떤 데이터가 등장할지를 예측하는 방식입니다. 하지만 당시 실험을 진행하면서 한 가지 아쉬운 점..
마이바티스에서는 SQL을 매핑하는 방식으로 크게 어노테이션 방식과 XML 방식을 제공하고 있습니다. 저는 이 중 어노테이션 방식을 선택하게 되었습니다. 가장 큰 이유는 멀티 모듈 구조에서 조금 더 관리하기 좋다고 느꼈기 때문입니다. 특히 어떤 기능이 어디에 존재하는지 추적하는 과정에서 어노테이션 방식이 더 직관적이라고 생각했습니다. 물론, 단점도 존재합니다. 복잡한 동적 쿼리를 작성하게 되면 XML 방식에 비해 불편함이 생길 수 있습니다. 그럼에도 불구하고 어노테이션 방식을 선택한 이유와, 왜 멀티 모듈 환경에서 잘 어울린다고 생각했는지 이번 글에서 정리해보려고 합니다.어노테이션 방식은 어떻게 사용할까?어노테이션 방식은 Mapper 인터페이스 위에 SQL을 직접 작성하여 사용하는 방식입니다.기존 XML처..
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가 재시작되더라도 메시지는 다시 전달되지..