발이 닿지 않는 바다에서
hajoeun.com
블로그에 올린 내용과 동일합니다!
https://velog.io/@soonmac/hh-plus-ai-week2-transformer
2주차 발제 및 과제 회고
이번 주에는 트랜스포머와 자연어 처리 관련 이론을 공부했다.
특히 어텐션 메커니즘이 엄청 어려웠다. 1주차만큼이나 어려운 내용이었는데, 부트캠프 측에서도 이걸 의식했는지 평일 저녁에 보충 세션을 추가해줬다.
이 보충 세션이 꽤 도움이 됐던 것 같다.
이번 주 과제는 트랜스포머를 직접 구현하는 거였는데, 이걸 제대로 이해하고 넘어가기 위해 과제 해설, 보충 세션 강의, 그리고 챗지피티까지 총동원해서 코드마다 주석을 달며 설명을 덧붙였다.
나는 이 수업을 듣는 목표가 AI 모델링 자체가 아니라, 이미 사전 학습된 AI 모델을 잘 다루고, 실제 서비스에 녹여내는 데에 있다.
그래서 수식이나 이론적으로 너무 깊은 부분은 과감히 스킵하고,
“이런 딥러닝 모델과 메커니즘이 있고, 대충 이렇게 굴러간다” 정도의 추상적인 이해에 집중하기로 했다.
그렇게 열심히 준비한 심화 과제에서 좋은 피드백을 받아서, 뿌듯했다ㅎㅎ
과제들은 전부 깃헙에 업로드하고 있다!
궁금하신 분들은 놀러오세요ㅎㅎ
https://github.com/sosososoyoen/hh_plus_ai_3/blob/main/work/week2/%EC%8B%AC%ED%99%94_Muti_Head_Attention.ipynb
멘토링 세션
이 부트캠프에선 매주 한 분의 코치님과 팀 단위 멘토링 세션이 진행된다.
나는 지금 회사에서 LLM 관련 프로젝트를 혼자 맡고 있는 상황이라, 실무에 대한 질문을 드렸다.
“규모가 작은 회사에서, 도메인에 특화된 LLM 챗봇을 만들 때 파인튜닝이 좋을까요? RAG가 좋을까요?”라고 물었는데,
코치님은 “파인튜닝은 비용이 많이 들고, 투자 대비 아웃풋이 확실하다는 보장도 없어서,
먼저 RAG와 프롬프트 엔지니어링으로 태스크를 해결해보는 게 좋다”고 하셨다.
ROI 관점에서 RAG가 더 낫다는 얘기였다.
우리 회사도 작고, 지금 이 프로젝트를 맡고 있는 개발자는 내가 유일하다.
그래서 당장은 RAG 방식부터 적용해봐야겠다는 확신이 들었다.
공부해야 할 게 또 늘었지만 ㅠㅠ
참고로 멘토링이 있었던 날이 4월 1일이었는데, 팀원분이 인프런 RAG 강의 만우절 세일 소식을 알려줘서…
바로 싸게 질렀다. 오예~
# 자연어 처리와 트랜스포머
NLP (자연어 처리)
- 컴퓨터가 인간의 언어를 이해하고 처리할 수 있도록 만드는 기술
- 컴퓨터는 인간의 언어를 이해할 수 없음 → 언어를 숫자로 변환해서 처리
“I am happy” → [”i”, “am”, “happy”] → [101, 102, 103]
- 문장을 토큰(단어)으로 쪼갠 후(tokenize) → 정수로 바꿈 (vocabulary)
### 워드 임베딩 기법
- 단어 → 숫자로 변환할 때 컴퓨터가 쓰는 기법
- 의미적으로 유사한 것들끼리는 비슷한 숫자로 변환
“Hi, how are you? Fine thank you.” → 워드 임베딩 → [1, 2, 13, 256]
- 1번째 인덱스 : 문장 그룹 형태. 여기서는 한 문장 그룹으로 인식함
- 2번째 인덱스 : 문장의 개수, 여기서는 2개
- 3번째 인덱스 : 토큰(단어)들의 개수
- 4번째 인덱스 : 임베딩 차원 수, 이 값이 높을수록 계산해야할 정보량도 늘어남. 하이퍼 파라미터 역할 (이건 개발자가 알아서)
- 임베딩 차원 : 단어를 숫자로 표현할 때 몇 개의 숫자로 표현할 지 정하는 것
- (번외) Word2Vec, glove
Word2Vec(워드투벡)
- 씨보우 : 주변 단어로 중심 단어를 예측
- 스킵그램 : 중심 단어로 주변 단어를 예측
glove(글로브)
- 통계를 통해 단어-단어 공기행렬을 사용해서 단어 벡터를 학습함
- 통계 정보를 활용해서 단어 간의 의미적 유사성을 반영함
- 공기행렬을 기반으로 단어들 사이의 의미적 유사성을 학습해서 단어 벡터를 만들어내는 모델.
공기행렬 (Co-occurrence Matrix): 단어들이 함께 등장한 횟수를 기록한 표.
단어 벡터 (Word Vector): 단어의 의미를 숫자로 표현한 벡터.
패딩 토큰 (padding token)
- 여러 문장이 입력되었을 때, 가장 긴 문장의 길이에 맞춰서 짧은 문장에 임의의 토큰을 집어넣는 것
- 딥러닝에서 쓰이는 데이터의 기본 형태 = 수학의 행렬이라서 열과 행을 맞춰야할 필요가 있음
- 사각형 틀에 들어간 물건들의 각이 흐트러지지 않도록 넣는 포장재를 생각하면 편하다
- [PAD]
토큰 : AI 모델이 분석할 때 무시하도록 설계된 특별한 토큰
"Hello, y'all!", 6개 토큰
"How are you 😁 ?", 5개 토큰
"I'm fine thank you and you?" 9개 토큰
토큰이 짧은 문장에 [PAD] 라는 토큰을 집어넣어서 문장의 길이를 맞춘다.
"Hello, y'all!" → ["Hello", ",", "y'all", "!", [PAD], [PAD], [PAD], [PAD], [PAD]]
"How are you 😁 ?" → ["How", "are", "you", "😁", "?", [PAD], [PAD], [PAD], [PAD]]
"I'm fine thank you and you?" → ["I'm", "fine", "thank", "you", "and", "you", "?", [PAD], [PAD]]
RNN - 순환신경망
- 시퀀스 데이터(문장, 음악, 주가 등) 처럼 순서가 중요한 데이터를 다룰 때 사용하는 인공신경망
- 이전의 학습 결과를 가지고 다시 입력으로 사용하여 반복적으로 학습함
- 이전 시점의 은닉 상태(hidden state) (= 기억 노트)를 다음 입력과 함께 다시 사용하여, 시간 흐름을 반영하며 학습함
- 하지만 단점이 존재:
- 문장이 길어질수록 앞쪽 단어의 정보가 점점 희미해지거나 사라짐
- 앞부분에 중요한 정보가 있음 ⇒ 모델이 이를 "기억 못한 채" 다음 작업을 하게 됨
- 이 문제를 해결하기 위해 LSTM, GRU 같은 구조가 등장했지만,
최근에는 Transformer 기반 모델들이 거의 대세가 되면서, RNN은 잘 사용되지 않음 (하지만 기초 개념으로 여전히 중요!)
시퀀스 투 시퀀스
- 기계 번역, 질의응답에서 쓰이는 모델
- 2개의 RNN을 연결한 형태(인코더, 디코더)
- 인코더 : 입력된 문장을 토큰(단어) 단위로 쪼개서 계산 → 최종 단계에서 전체 문장의 정보를 하나의 벡터로 요약해서 디코더에게 전달함
- 디코더 : 인코더에서 나온 요약 벡터를 토대로 출력 문장을 생성함
- 단점 : RNN 2개를 연결한 거라서, RNN의 단점을 그대로 가져옴
- 문장이 길어질수록 정보값들이 작아지고, 최종 요약단계에서 중요한 정보가 손실될 가능성이 높다.
- 디코더도 이 요약된 벡터만 가지고 문장을 생성하기 때문에 오답을 생성할 가능성이 높다.
⇒ 그래서 등장한 것이 어텐션! 어텐션의 시대가 온 것이다…
🌟 어텐션 메커니즘
단어가 입력될 때마다 갱신되는 모든 은닉 상태(hidden state) 값을 모두 저장
- 디코더가 출력 단어를 하나씩 생성할 때마다 인코더의 은닉 상태 전체를 참고한다.
- 이 때 디코더는 인코더의 은닉 상태 중 어떤 값에 집중할지(=어디에 Attention 할 지) 가중치로 계산한다
⇒ 전체 은닉 상태(hidden state)를 활용해 출력할 때마다 가장 중요한 단어에 집중(Attention!)
🌟🌟트랜스포머
- 그러나 RNN에게는 아직 단점이 하나 더 남아있었다.
- 바로 RNN에서는 토큰을 하나씩 처리하는 방식이라 병렬적으로 작업을 못함 ⇒ 비효율적
- RNN을 버리고, 오직 어텐션만 가지고 데이터를 처리하자는 새로운 모델이 등장 ⇒ 트랜스포머
- 트랜스포머 vs RNN : RNN은 단어를 순서대로 기억하고, 트랜스포머는 모든 단어를 한 번에 비교 후, 중요도를 매긴다
⚙️ 작동 과정
포지셔널 인코딩
- RNN은 데이터를 순서대로 처리하는데 트랜스포머는 RNN을 사용하지 않아서 순서의 개념이 없다.
- 그래서 트랜스포머의 인코더에 넣기 전에 따로 위치 정보를 포함하는 벡터를 만들어줘야하는 데 이것이 바로 포지셔널 인코딩!
- 인코딩한 값은 -1~1 사이의 값을 갖고 있고, 모든 단어는 같은 차원의 벡터 값(=행의 개수가 같은 행렬)을 공유함
- 트랜스포머 인코더에 들어가는 입력값 = 입력 토큰의 임베딩 벡터(토큰을 숫자로 변환한 값) + 포지셔널 인코딩의 위치 정보 값
🌟🌟🌟셀프 어텐션
- 문장 내 단어들 간의 관계를 계산 → 중요한 단어에 선택적으로 집중해서 문맥을 파악하도록 함
- 행렬곱이 아주 중요한 키워드라서 공식을 첨부함

- 행렬곱 = (m x k ) * (k x n) = m * n
⚙️ 작동 원리
1. 문장이 입력되면 토큰 단위로 쪼갠 후, 각 토큰마다 쿼리, 키, 밸류 Q,K,V 이 3가지 요소를 가지고 계산을 시작함.
Query (Q) | 내가 찾고 싶은 정보 | 현재 단어가 어떤 정보를 찾고 싶은지 표현
Key (K) | 모든 단어가 가진 특징 | 각 단어가 어떤 정보(특징)을 갖고 있는지 표현
Value (V) | 실제로 전달할 정보 | Key와 연결된 실제 의미
1. 입력값 x에 각각 가중치 행렬을 곱해서 Q, K, V의 값을 생성한다.
1. 가중치 행렬은 초기값을 랜덤하게 세팅함
2. 쿼리와 키의 유사도를 구한다
- “나는”이라는 단어가 있으면 해당 단어의 쿼리 값과 키값을 곱해보고, “학생” 같은 다른 단어의 키값과도 곱해보면서 각 토큰에 대한 유사도를 구한다.
- Q 행렬 * K의 전치행렬 (행과 열이 바뀐 행렬)
- K를 전치하는 이유는, 행렬곱의 조건 (m x k ) * (k x n) 을 맞추기 위해서
각 토큰별로 구한 유사도를 스케일링한다.
1. 값이 너무 크거나 작으면 학습할 때 불안정할 수 있어서 스케일링을 통해 안정화 시킴
softmax로 0~1 사이의 숫자로 만들어서 확률값으로 바꾼다. (=어텐션 스코어 = 중요도)
위에서 구한 각각의 어텐션 스코어를 각 토큰의 value에 곱한 후, 이를 더해서 중요도를 반영한 문맥 데이터로 변환한다.
디코더에서 이를 가지고 새로운 문장을 출력함
🥺 쉽게 설명하자면..
1. “고양이가 침대 위에서 잔다”라는 문장이 입력됨
2. 어텐션 메커니즘이 이 문장을 단어 별로 쪼갬
고양이가, 침대, 위에서, 잔다
3. 이 쪼갠 단어 별로 쿼리, 키, 밸류 값을 생성함
1. 쿼리 : 현재 단어가 어떤 정보를 찾고 싶은지 표현
2. 키 : 각 단어가 가진 특징
3. 밸류 : 키와 연결된 실제 의미
4. 위에서 구한 쿼리, 키, 밸류값을 통해 각 단어의 중요도를 계산해서 점수를 매김
5. 중요도 점수가 높은 토큰들 위주로 최종 요약을 생성해낸다.
#항해99 #항해 플러스 AI 후기 #AI 개발자 #LLM
다음 내용이 궁금하다면?
이미 회원이신가요?
2025년 4월 6일 오전 11:45
1. 이 세계에 존재하는 책의 99.99%를 저는 아직 읽은 적이 없습니다. 그 사실 앞에서 망연자실해집니다.
사람들은 대체로 자신을 높이고 싶어 한다. 그래서 남들이 쉽게 하지 못하는 일에 도전하기도 하고, 독보적인 성과를 내려고 노력하기도 한다. 때로는 타인을 억압하거나 폭력을 행사함으로써 자신을 높이려는 사람들도 보인다.
... 더 보기이 친구도 만만치않게 독특한 편
... 더 보기카
... 더 보기J
... 더 보기