728x90
반응형




Open LLM Model을 활용하여 Fine Tuning한 모델을 가지고 실제 비즈니스에 적용한 서비스를 만들기 위해
LLM을 테마로 하여 LLM 모델에 대한 개요와 원리 등을 공부하여 블로그로 연재하겠습니다.


먼저 본 글에서는 현재까지의 LLM 발전기에 대해 다뤄보겠습니다.


딥러닝 기반 언어모델의 등장

LLM(Large Language Model)이란? 인간이 활용하는 수많은 자연어를 학습한 딥러닝 기반의 언어모델입니다.



LLM은 딥러닝 기술을 통해 더욱 효율적이고 개선된 성능으로 자연어 처리 및 생성을 수행하기 때문에 위 사진과 같은 벤다이어그램으로 표현할 수 있습니다.


딥러닝의 자연어 처리 분야 적용

RNN(Recurrent Neural Network)이란? 순환신경망, 자연어 문장과 같은 시퀀스한 입력데이터를 받는 모델입니다. 입력으로 주어지는 시퀀스한 데이터의 순서가 달라질 경우, 모델이 의미를 다르게 해석하여 출력도 달라질 수 있습니다.



RNN의 개념부터 다른 이유는 RNN이 자연어 문장과 같은 시퀀스 데이터를 처리하기 위해 처음 등장한 모델이기 때문입니다. (1986년 등장)


위 그림에서 볼 수 있는 것처럼 RNN모델은 토큰(단어) 단위 현재 시점의 입력 정보와 과거 시점의 출력 정보 두 개의 정보를 입력하여 연속적으로 학습시킬 수 있습니다. 하지만 입력 정보의 길이가 길어짐에 따라 학습도 길어지게 되면 오래된 정보일수록 의미가 희미해지는 현상이 발견됩니다. (Vanishing Gradient) 그래서 1997년 아래와 같은 아키텍처의 모델이 등장하게 됩니다.


  • LSTM (Long Short Term Memory)




입력 정보가 길어질수록 과거 정보의 의미가 희미해지는 현상을 보완하기 위해 LSTM 아키텍처가 등장하게 됩니다.
위 그림에서 볼 수 있는 것처럼 LSTM 아키텍처는 각 노드마다 과거 시점의 입력 정보를 추가로 받고,
게이트 단에서 세 개의 입력정보 (과거 시점 입력정보/과거 시점 출력정보/현재 시점 입력정보)를 입력받아서 데이터 활용여부와 방법을 결정하게 됩니다.
자세한 내용은 추후 작성될 RNN글에서 다뤄보겠습니다.


그럼에도 불구하고 과거 시점의 의미가 희미해지는 현상이 완전히 해소되지 않아서 숙제로 남게됩니다.


딥러닝의 대두

2012년 이미지 인식 대회인 ImageNet에서 딥러닝 기술을 활용한 AlexNet 모델이 우승하였습니다.
당시에 AlexNet 모델은 기존 방식을 활용한 이미지 인식 모델의 오류율을 크게 개선하였는데요.
뿐만 아니라 해당 모델을 특정 문제를 해결하는데 뿐만 아니라 다른 문제를 해결하는 데에도 범용적으로 활용할 수 있어서
해당 사건을 계기로 딥러닝 기술에 대한 사람들의 관심이 다시 높아졌습니다.


AlexNet 모델은 대표적은 CNN(Convolutional Neural Network) 모델입니다. 다음에 기회가 된다면 상세히 살펴보겠습니다.


Word2Vec 기술 등장

2013년, 구글의 연구원들은 Word2Vec 이라는 기술을 개발하게 됩니다.
Word2Vec 기술은 단어를 실수벡터 형태로 변환하는 기술입니다. 그리고 실수벡터 형태로 변환하는 과정을 Embedding이라고 합니다.




  • 등장 배경

컴퓨터가 이해할 수 있도록 자연어를 숫자로 변환하는 방식인 One-Hot 인코딩은 표현하고자 하는 단어의 인덱스를 1로, 나머지 단어의 인덱스는 0으로 세팅하는 방식입니다. 하지만 해당 방식은 단어 간의 유사성을 확인할 수 없다는 단점이 있었습니다.
이러한 단점을 보완하기 위해 Word2Vec 기술이 등장하게 됩니다.


  • 유사성을 벡터화하는 방법

단어간의 유사성 정보를 어떻게 벡터에 담을 수 있을까요?
Word2Vec을 관통하는 핵심 개념은 "비슷한 문맥에서 등장하는 단어들은 비슷한 의미를 가진다." 입니다.
강아지라는 단어는 귀엽다, 예쁘다 등의 단어가 주로 함께 등장하는 것처럼요.


위 개념을 기반으로 하는 분포 가설이라는 것을 정의하고,
정의한 분포 가설을 활용하여 학습한 모델에 자연어를 입력하면,
해당 자연어는 유사성 정보가 담긴 벡터로 변환됩니다.


자세한 내용은 👉Embedding글에서 참고 바랍니다.


Transformer 모델의 등장

2017년, 자연어 처리 분야의 딥러닝 연구가 지속되고 있는 중에 구글의 연구진은 "Attention is All you need"라는 논문을 통해 Transforemer 모델 아키텍처를 공개하게 됩니다. 해당 모델은 학습 텍스트가 길어질수록 과거의 정보가 희미해지는 RNN의 고질적인 문제를 획기적으로 해결하였습니다.
RNN의 순차 처리방식을 버리고 맥락을 모두 참조하는 Attention 연산을 이용한 것입니다.


그리고 현재까지 해당 트랜스포머 모델을 기반으로 구글, 메타, OpenAI 등 주요 테크기업을 중심으로 여러 LLM 모델이 개발되거나 개발중이고,
OpenAI의 ChatGPT 서비스가 일반 사용자에게 공개됨에 따라 AI에 대한 대중의 관심이 크게 증가하여
다양한 분야에 LLM을 접목하는 시도가 많이 나타나고 있습니다.


트랜스포머 모델의 자세한 내용은 다음 글에서 다뤄보겠습니다.


Reference

반응형
728x90
반응형




1. Kafka 란?

Kafka란? Event 기반의 Pub-Sub 연동을 가능하게 하는 메세지 큐 시스템. MSA 환경에서 많은 Micro Service간 결합을 풀어서 서비스간 영향도를 최소화시켜주는 역할을 합니다.



Kafka의 역할

  1. 메세징 시스템
  2. 모니터링 데이터 수집
  3. 로그 수집
  4. 시스템간 종속성 분리 등


2. Kafka 아키텍처

위 Kafka 아키텍처에 대해 간단한 설명을 덧붙이자면,

  1. MSA 환경에서의 Micro Service는 각각 Producer와 Consumer의 역할을 수행
  2. Producer는 Application 자체에서 정의된 규칙에 따라 이벤트가 발생
  3. 이벤트가 발생했을 때, Producer는 Json 형태의 메세지를 Kafka 큐 시스템에 발송
  4. 발송된 메세지를 구독한 Consumer 서버가 해당 메세지를 수신


이제 Kafka를 구성하는 요소들에 대해 하나씩 알아보겠습니다.


Topic

  • Topic : Application으로부터 많은 메세지가 Kafka 서버를 통해 송수신이 되는데, 이러한 메세지들을 구분하기 위한 저장소? 데이터 스트림? 논리적 집합이라고 보면 됨 > application간 메세지는 kafka topic을 통해 전송됩니다.


  • application의 이용량이 많아질수록 서버간 송수신되는 메세지가 많아지는데, 이러한 대용량 트래픽을 잘 처리하기 위해 토픽마다 파티션 기능을 활용할 수 있습니다.


Partition

  • Parition : application에서 전송된 메세지를 선입선출 방식으로 적재하는 큐 형태의 저장소 -> producer로부터 전송받은 메세지를 consumer에서 선입선출 방식으로 메세지를 읽어와 처리합니다.


Partition 병렬처리

  • 목적 : 토픽당 여러개의 Partition을 생성하여 많은 양의 메세지를 빠르게 처리할 수 있습니다. -> Partition을 늘리는 것은 가능하나 줄이는 것은 불가


  • 병렬처리 특징

  1. Partition당 Consumer의 메세지 처리 순서를 보장하기 위해 메세지별로 index를 부여하고, offset을 계산하여 다음 읽을 메세지를 Consumer에서 곧바로 확인할 수 있습니다.
  2. Partition별 index 및 offset 계산은 독립적으로 수행 -> 동일 Partition에 메세지를 전송하면 Consumer에서의 처리순서를 보장할 수 있지만, 다른 Partition으로 메세지를 전송하면 순서를 보장할 수 없습니다.
  3. 동일 key값이 부여된 메세지는 동일 partition에 적재 -> 메세지별로 동일 key값을 부여하는 방식으로 병렬처리 환경에서의 메세지 처리 순서를 보장할 수 있습니다.


Broker

  • Broker : kafka 클러스터를 구성하는 각각의 kafka 서버


  • 특징

  1. 각각의 broker는 topic/partition을 가짐
  2. 어떤 broker에 접속해도 전체 kafka cluster에 접속 가능
  3. 3개부터 100개까지 늘어날 수 있음


Zookeeper

  • Zookeeper : kafka broker를 관리 -> kafka 3.3 버전 이후 zookeeper는 deprecated될 예정


  • 역할

  1. partition의 리더 선출 (리더는 write/read, 서브는 read만 수행)
  2. kafka 클러스터의 변경사항에 대한 알림


Topic Replication Factor

  • Topic Replication Factor : topic별 partition 복제를 위한 설정 값 (ex. 값이 2일 경우, 파티션을 두개로 복제)
  • 아래 사진은 Topic A의 파티션이 2개, Topic Replication Factor가 2일 때의 예시




  • 특징
  1. 특정 broker에 장애가 발생하여 해당 broker가 수용하는 partition이 제기능을 못할 경우, 다른 broker에 수용되어 있는 다른 복제본이 기능을 대신 수행 -> leader 파티션이 기능을 못할 경우, leader 역할을 복제본으로 변경
  2. 토픽의 데이터가 3GB일 때, Replication Factor가 2이면 해당 토픽의 전체 용량은 6GB


3. Pub-Sub 연동

  • MSA에서 Micro Service간 약결합 연동을 위해 비동기 메세징 방식의 pub-sub 연동을 활용할 수 있습니다. -> 비동기 메세징 방식을 위한 Data Stream으로 kafka가 활용됨




Producer

  • Producer : 메세지를 생산하여 토픽으로 메세지를 보내는 application 혹은 서버
  • 특정 토픽 및 파티션으로 메세지를 보낼 때, 메시지의 key 값을 설정한다면 특정 partition에 전송되도록 할 수 있습니다. -> key값이 없다면 라운드로빈 방식으로 파티션 지정하여 메세지 전송




  • acks (메세지 전송 보장을 위한 producer 설정)
  1. acks=0 : kafka의 응답을 기다리지 않음 (메세지 손실 가능성은 높지만 빠른 전송 필요)
  2. acks=1 (default) : 리더 partition의 응답만 대기 (메세지 손실 가능성이 적고 적당한 속도의 전송 필요)
  3. acks=all : 리더 및 ISR partition의 모든 응답 대기 (메세지 손실은 없지만 전송 속도 느림)


Consumer

  • Consumer : 토픽에 저장된 메세지를 가져가는 application 혹은 서버

  • Consumer Group : Consumer들의 집합, kafka 데이터를 처리하는 단위 -> Consumer Group과 Partition은 1대1 매칭만 가능 -> 동일 Consumer Group내 A Consumer가 A 파티션과 연동하고 있다면, 다른 B Consumer에서 해당 A 파티션은 연동 불가


  • 특징

  1. Consumer Group은 메시지를 가져간 후, offset을 해당 partition에 커밋
  2. kafka는 내부적으로 별도 partition을 통해 커밋 정보 관리




4. Kafka Scaling

  • kafka는 메세지 가용성 및 효율성을 위해 여려가지 Scaling 기능을 제공합니다.


Broker 스케일링

  • Kafka 클러스터내 모든 Broker의 리소스 사용률이 현저하게 높을 경우, 새로운 Broker를 추가할 수 있습니다.


  • 방법

  1. 고유 ID를 부여한 새로운 Broker를 추가한 후 Zookeeper Ensemble에 연결합니다.




  1. kafka-reassign-partitions 명령어로 Topic별 파티션을 리밸런싱 합니다.




Partition 스케일링

  • Producer에서 파티션으로 메세지 저장에 병목이 발생할 경우, 해당 topic의 파티션을 증가시킬 수 있습니다.




  • 주의사항
  1. 파티션 수가 많을수록 파일 핸들러가 증가하므로 적절한 개수의 파티션 설정 필요
  2. 증가만 되고 줄이는 방법은 없으므로 목표 처리량의 기준설정 필요
  3. Consumer Group내의 Consumer 갯수와 동등한 파티션 갯수 설정 필요


  • 방법




Consumer 스케일링

  • 메세지 처리 지연(Message Lagging)이 발생할 경우, 메세지 처리를 수행하는 Consumer를 증가시킬 수 있습니다.
  • Message Lag : Producer Pub 메세지와 Consumer Sub 메세지간 Offset 차이




  • 스케일링 과정
  1. Consumer 추가 (Scale-Out)
  2. 각 Consumer Group당 코디네이터(Coordinator)가 Consumer 수 변경을 인지하게 되면 리밸런싱(소유관 이관) 작업을 진행 -> 파티션-Consumer 관계를 재배치
  • 리밸런싱 : Consumer Group의 파티션 소유권을 재할당하는 작업 -> Producer의 메세지는 모든 파티션에 균등하게 배분


  • 리밸런싱 조건

  1. Consumer Group 코디네이터가 특정 Consumer의 장애로 판단할 경우 리밸런싱 진행 -> Consumer가 메세지를 폴링하거나 offset를 커밋할 때마다 해당 Group 코디네이터에 HeartBeat 메세지를 전송 -> 특정 시간동안 HeartBeat 메세지가 없는 Consumer를 장애로 판단
  2. 특정 Consumer Group내 Consumer 수 변경
  3. 특정 토픽의 Partition 수 증가


Replication Factor

  • 리더 파티션의 장애를 대비하여 Replication Factor 값 설정을 통해 파티션을 복제할 수 있습니다.




  • 방법




5. 병렬환경에서의 처리순서 보장을 위한 메세지 처리 과정

반응형

'개발 > MSA' 카테고리의 다른 글

[MSA] API Gateway  (0) 2024.11.07
[MSA] 헥사고날 아키텍처와 MSA 전환  (0) 2024.11.03
DDD와 Event Storming  (3) 2024.11.02
[k8s] kubernetes 클러스터  (1) 2024.04.06
[k8s] kubernetes란?  (0) 2024.02.29
728x90
반응형




👉이전글(헥사고날 아키텍처와 MSA전환)에서 살펴본 것처럼 MSA 전환 시에는 API Gateway 모듈이 활용될 수 있습니다.


이러한 API Gateway는 MSA 전환 시, 레거시와 Micro Service간의 통합을 도와주는 역할 뿐만 아니라
Micro Service중 하나로서 다양한 역할을 수행합니다.


이번글에서는 API Gateway 개요와 다양한 역할, 구현 방법에 대해 소개하고
Rest API를 통한 요청-응답 시에 전체모듈로 장애확산을 방지하는 Circuit Breaker 기능에 대해서도 알아볼 것입니다.


API Gateway

API Gateway란? API Gateway는 백엔드 서비스 앞단에서 모든 API 서버들의 엔드포인트를 단일화하여 요청에 대한 라우팅 기능을 수행하고, 인증/인가 기능과 API 호출 로깅(logging) 기능 등 각 벡엔드 서버의 공통 기능을 수행하는 단일 모듈입니다. 이를 통해 뒷단의 각 백엔드 서버는 공통 기능을 별도로 구현하지 않아도 됩니다.



위 언급된 API Gateway의 많은 기능 중 본 글에서는 단일 진입점으로서의 라우팅 기능과 인증/인가 기능을 살펴볼 것입니다.


Routing

Routing 기능은 API Gateway의 대표적인 기능중 하나로서,
client에서 특정 Rule기반으로 API Gateway를 호출하기만 하면
해당 Rule에 맞게 뒷단의 백엔드 서버를 찾아서 요청을 전달해줍니다.


라우팅 Rule 유형은 다양하지만 일반적으로 Path 기반으로 라우팅하게 됩니다.
예를들어, http://{GATEWAY_IP}/order uri로 요청한다면 order micro service로 routing하고,
http://{GATEWAY_IP}/inventory uri로 요청한다면 inventory micro service로 요청을 routing하는 방식입니다.


MSA 환경에서 Gateway를 구현하는 방식은 다양합니다.
대표적으로 java언어 기반의 SpringCloud 프레임워크를 활용하는 방식이 있고,
kubernetes 인프라의 Ingress 모듈을 활용하는 방식이 있습니다.


SpringCloud vs Ingress

요약하자면,
SpringCloud는 Java 기반의 프레임워크이기 때문에 Java 기반의 application과 호환이 잘되고,
Java/SpringBoot의 편리한 기능을 모두 활용할 수 있기 때문에 Java 개발자에게 편리할 수 있습니다.
하지만, JVM을 지원하지 않은 다양한 스택의 application과 연동해야할 때, 다양한 기술스택 활용을 장려하는 MSA 환경 특성상 SpringCloud 활용이 부적절할 수 있습니다.


Kubernetes Ingress는 특정 언어 기반으로 구현해야하는 application이 아니고,
Kubernetes의 type중 하나로 실행되는 Gateway 템플릿이기 때문에 특정 환경에 종속되지 않아서
다양한 기술스택을 수용해야 하는 MSA 환경에 적합할 수 있습니다. (실제 Routing 기능을 수행할 nginx와 같은 app을 Ingress Controller로서 별도 설치 필요) 또한, programming 기반이 아닌 Menifest 파일 기반으로 routing rule을 설정할 수 있습니다.


요약만 보면 Ingress를 선택해야하는 것이 아닌가 생각이 들겠지만,
Spring기반으로 Filter를 커스터마이징할 수 있고, Path rewriting 등과 같은 기능을 활용할 수 있어
Gateway로 SpringCloud를 선택하는 경우도 있다고 합니다.


구현방법 (SpringCloud Gateway)

  1. Gateway로 활용할 SpringBoot 프로젝트를 생성합니다.


  2. 해당 프로젝트에 아래 dependency를 추가합니다

    <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>



  3. 프로젝트 resources의 application.yml에 아래 routing rule을 설정합니다.

    spring:
    profiles: default
    cloud:
     gateway:
       routes:
         - id: monolith
           uri: http://localhost:8082
           predicates:
             - Path=/orders/**, 
         - id: inventory
           uri: http://localhost:8083
           predicates:
             - Path=/inventories/**, 
         - id: frontend
           uri: http://localhost:8080
           predicates:
             - Path=/**



위와 같이 설정을 완료하고 특정 호스트에 맞는 path를 Gateway url에 붙여 http 요청한다면,
해당 호스트로 요청이 routing 됩니다.
위 설정 기반으로 예를들면, http://{GATEWAY_IP}/orders에 요청했을 때 http://localhost:8082의 monolith 호스트로 routing 됩니다.


위 application.yml의 predicates 속성을 잘 활용한다면,
path 기반 rule 뿐만 아니라 다양한 요청 rule 기반으로 요청이 routing될 수 있도록 설정할 수 있습니다.

반응형

'개발 > MSA' 카테고리의 다른 글

[MSA] Kafka  (0) 2024.12.14
[MSA] 헥사고날 아키텍처와 MSA 전환  (0) 2024.11.03
DDD와 Event Storming  (3) 2024.11.02
[k8s] kubernetes 클러스터  (1) 2024.04.06
[k8s] kubernetes란?  (0) 2024.02.29
728x90
반응형




이전글에서 MSA개요와 Event Storming에 대해 다뤘고,
👉MSA개요
👉Event Storming
이번글부터는 MSA 구현방법을 하나씩 다뤄보겠습니다.

헥사고날 아키텍처 (Hexagonal Architecture)

MSA의 서비스 구현은 기본적으로 헥사고날 아키텍처를 준용합니다.

헥사고날 아키텍처란? 느슨하게 결합된 MSA 서비스 구현을 목표로
Micro Service 단위로 분리된 각 서비스마다 외부와의 연동을 위한 In/Out-Bound Adapter, DB접근을 위한 ORM을 구성하고,
서비스(도메인)별 언어활용을 통한 코드 작성 및 기술적 구현을 진행하는 아키텍처




위 사진과 같이 헥사고날 아키텍처를 준용하여 서비스를 구현한다면 MSA 목표인 독립성을 달성할 수 있을 것으로 기대합니다.

아래는 SpringBoot 기반의 헥사고날 아키텍처를 표현한 사진입니다.




Event Storming to SpringBoot

👉이전글에서 언급한 Event Storming을 활용하여 MSA 서비스를 설계한다면,
보다 쉽게 헥사고날 아키텍처를 준용하여 SpringBoot기반의 서비스를 설계할 수 있습니다.

아래는 Event Storming 스티커와 SpringBoot 모듈간 매핑 관계입니다.

  1. Bounded Context : SpringBoot 서버 자체
  2. Domain Event : 외부 서비스로의 연동전 Java 객체
  3. Command : RestController, Repository
  4. Aggregate : JPA or MyBatis or SpringCloud Stream Publisher
  5. Policy : SpringCloud Stream Listener




MSA 전환

레거시에서 MSA로의 전환을 시작할 때, 일반적으로 아래 내용이 검토되어야 합니다.




그리고 Strangler 패턴을 적용하여 보다 안정적인 전환이 가능합니다.

Strangler 패턴이란? 레거시 모놀리스에서 Micro Service로 구현할 일부 모듈을 점진적으로 확대 분류하여 Micro Service로 구현함으로서
MSA 전환 시, 비즈니스 영향도를 최소화하는 패턴







해당 Strangler 패턴을 적용하기 위해서는 MSA로 분리된 서비스와 기존 모노리스를 어떻게 연동할 지에 대한 방법을 고민해야 합니다.
아래는 레거시와 MSA간 API 통합 방법입니다.

  1. API Gateway : 단일 진입점, URL 기반의 라우팅 수행
  2. Service Registry : MSA의 단일 진입점(API Gateway)을 구성하여 API Gateway가 MSA 클러스터 내의 인스턴스를 찾아갈 수 있도록 하는 방법


레거시와 MSA 서비스간의 단일 진입점인 API Gateway를 구성하여 URL 기반의 라우팅이 되도록 구성한다면,
MSA로의 점진적 전환을 위한 Strangler 패턴을 적용할 수 있습니다.

예를들어, Front 모듈에서 Back 모듈로 임의의 요청을 보낼 때의 url로 레거시 서비스와 MSA 서비스를 구분할 수 있다면,
API Gateway에서의 간단한 설정을 통해 url을 통해 레거시와 MSA를 구분한 라우팅이 가능하도록 설계할 수 있습니다. 이를 통해 레거시와 MSA를 통합할 수 있죠.




API Gateway와 Service Registry의 자세한 내용은 추후 별도 글로 다뤄보도록 하겠습니다.


Reference

  • 사내 강의 (Developing Cloud Native Application) - 박용주 강사님
반응형

'개발 > MSA' 카테고리의 다른 글

[MSA] Kafka  (0) 2024.12.14
[MSA] API Gateway  (0) 2024.11.07
DDD와 Event Storming  (3) 2024.11.02
[k8s] kubernetes 클러스터  (1) 2024.04.06
[k8s] kubernetes란?  (0) 2024.02.29

+ Recent posts