챗봇 만들기 2탄 (질문과 응답을 개선)
# 챗봇 만들기 2탄
챗봇을 만들어보자, 질문과 응답을 개선해 보자.
1. 데이터 셋
데이터 셋을 바꿔서 전처리를 수행하고 질문과 응답을 구현했다.
데이터 셋의 데이터는 아래의 링크에서 활용했다.
https://github.com/songys/Chatbot_data
2. 코드
파이썬 코드는 아래와 같다.
이전에 생성한 코드에서 데이터 셋의 경로와 데이터 셋 전처리 부분만 바꾼 후 테스트 데이터 약 1000개를 별도로 저장 후 진행 했다. (코드는 참고용)
2024.09.19 - [연구 과제 (끝나면 해당 카테고리로 이동)] - ChatBot(챗봇) 만들어보기
3. 결과
결과를 한번 보자.
인터페이스도 이전의 코드를 그대로 활용했다.
일단 학습 트레이닝 결과를 보면 아래와 같다.
결과 원문은 아래와 같다.
Map: 100%|██████████| 1110/1110 [00:00<00:00, 9811.13 examples/s]
60%|█████▉ | 500/834 [22:45<14:47, 2.66s/it]{'loss': 0.3653, 'grad_norm': 1.855972409248352, 'learning_rate': 2.0023980815347724e-05, 'epoch': 1.8}
100%|██████████| 834/834 [37:47<00:00, 2.72s/it]
{'train_runtime': 2267.9159, 'train_samples_per_second': 1.468, 'train_steps_per_second': 0.368, 'train_loss': 0.2718260374000604, 'epoch': 3.0}
3-1. 결과 분석
결과를 분석하면 아래와 같다.
- *데이터셋 처리 속도
*데이터셋의 1110개의 예제를 처리하는 데 걸린 시간은 매우 짧은 편이다. (00:00 <00:00,9811.13 examples/s
) - *훈련 진행 상황
*전체 훈련 과정의 60% 지점에서 500번째 스텝까지 진행되었을 때의 상태이다.
(60%|█████▉ | 500/834 [22:45 <14:47, 2.66s/it]
)
이 시점에서의 손실 값(loss
)은 0.3653이며, 그래디언트 노름(grad_norm
)은 1.855972409248352이다.
학습률(learning_rate
)은 2.0023980815347724 e-05이고, 에포크(epoch
)는 1.8이다. - *최종 훈련 결과
*전체 834 스텝을 완료하는 데 걸린 시간은 약 37분 47초이다.
(100%|██████████| 834/834 [37:47 <00:00, 2.72s/it]
)
최종 훈련 시간(train_runtime
)은 2267.9159초입니다.
초당 처리된 샘플 수(train_samples_per_second
)는 1.468입니다.
초당 처리된 스텝 수(train_steps_per_second
)는 0.368입니다.
최종 훈련 손실 값(train_loss
)은 0.2718260374000604입니다.
최종 에포크(epoch
)는 3.0입니다.
이 결과를 통해 모델이 3 에포크 동안 훈련되었으며, 최종 손실 값이 0.2718로 비교적 낮은 편임을 알 수 있다. 이는 모델이 주어진 데이터셋에 대해 잘 학습되었음을 나타낸다.
4. 테스트
테스트해보니까 또 동문서답을 하고 있다.
뭐가 잘못된 걸까...
일단 파라미터 값을 조정해서 다시 학습을 시켜 보기로 했다.
아래의 표를 보면 추가로 변경한 옵션은 에폭수, 배치크기, 학습률, 모델 저장 주기, 저장할 체크포인트, 가중치 감쇠 로그 관련 정보를 수정하거나 추가하였다.
Parameter | Original Value | Updated Value | Description (Korean) |
---|---|---|---|
output_dir |
./results |
./results |
결과물이 저장될 디렉토리 |
num_train_epochs |
3 | 5 | 학습 에폭 수 |
per_device_train_batch_size |
4 | 8 | 각 장치당 배치 크기 |
learning_rate |
Not specified | 5e-5 | 학습률 |
save_steps |
10,000 | 5,000 | 모델 저장 주기 (스텝 수) |
save_total_limit |
2 | 3 | 저장할 체크포인트 수 |
weight_decay |
Not specified | 0.01 | 가중치 감쇠 |
logging_dir |
Not specified | ./logs |
로그가 저장될 디렉토리 |
logging_steps |
Not specified | 200 | 로그 기록 주기 (스텝 수) |
변경한 값을 기준으로 재 학습을 시도...
시간이 이전의 학습 시간보다 2배가 더 소요된다. (노트북이 못 받쳐주는 것도 있다. AMD 5700U 16GB 그래픽은 내장형...)
일단 학습이 끝날 때까지 기다린 뒤에 다시 한번 질문을 하고 답변을 기다려보자.
학습 데이터량을 늘린 게 아니라서 크게 드라마틱한 답변의 향상은 기대하기는 어렵겠지만...
5. 1차 학습에 대한 결과 분석
학습이 완료되어도, 응답이 크게 개선되진 않았다.
새로운 방법을 생각해야 하는데, 일단 학습이 진행되는 동안 모델의 성능을 향상하기 위한 몇 가지 방법을 Search 해서 보면 아래와 같다.
1. 데이터 증강(Data Augmentation): 데이터셋을 확장하여 모델이 더 다양한 패턴을 학습할 수 있도록 한다. (가능)
2. 하이퍼파라미터 튜닝(Hyperparameter Tuning): 학습률, 배치 크기, 에폭 수 등을 조정하여 모델의 성능을 최적화한다. (가능)
3. 모델 아키텍처 변경(Model Architecture Change): 더 큰 모델이나 다른 모델 아키텍처를 사용해 볼 수 있다. (불가)
4. 전이 학습(Transfer Learning): 사전 학습된 모델을 사용하고, 특정 도메인에 맞게 미세 조정한다. (가능)
5. 정규화 기법(Regularization Techniques): 드롭아웃(Dropout)이나 가중치 감쇠(Weight Decay) 등을 사용하여 과적합을 방지한다. (드롭아웃은 모델이 더 다양한 특징을 학습하도록 도와준다,
가중치 감쇠는 모델이 더 간단한 가중치 값을 가지도록 유도하여 과적합을 방지한다.) (가능)
위의 모델의 성능을 향상하기 위한 작업으로 여기서는 하이퍼 파라미터 튜닝과 정규화 기법만 적용하여 동일하게 테스트를 진행했으나 결과는 크게 나아지지 않았다.
남은 건 데이터의 증강이라고 생가 되어 데이터 셋의 크기를 10배 늘려서 학습을 시켜보고 결과를 테스트하고자 한다.
6. 2차 학습 (데이터 10배 증가)
학습 시간이 너무 많이 소요되어 LoRA(Low-Rank Adaptation of Large Language Models)를 적용하여 학습을 수행하고자 한다.
- 학습 시작
데이터 크기를 10배로 하고 학습을 시작하니... 25시간이 걸린단다. 음 사이즈를 10배 말고 3배로 줄이고 학습을 해보자.
- 3배로 학습 시작
3배로 해도 8시간이 걸린다... 5시간 내외로 끝내게끔 데이터 사이즈를 조정하자.
- 전체 데이터의 6분의1인 2천 건 정도로 테스트를 진행해 보자.
약 4시간이 소요된다.
최초에 학습했던 데이터 건수는 약 200건으로 매우 적었다. 그래서 학습시간도 10분 내외로 끝났고,
이제 최초 학습건수의 10배인 2000건을 학습했을 때의 결과는 어떨까. 좀 더 나은 응답을 해줬으면 하는 바람이다.
7. 결과 확인
전체 데이터는 약 1만 1천여 개이다. 1만 1천여 개의 데이터 중에서 2천여 개만 일단 학습을 진행했다.
시간은 약 5시간이 소요되었으며, 성능 좋은 노트북이나 디바이스로 할 경우에는 학습시간이 상당히 단축될 것으로 예상한다. 학습 시간 단축을 위해서 Low-Rank Adaptation of Large Language Models를 적용하였고, 학습 시간을 상당히 단축시킬 수 있었다.
결과를 보면 아래와 같다. 이전보다는 상당히 답변이 간결해지고 허튼소리를 하는 비중이 많이 줄었다.
원본 데이터의 20%만 학습시켰는데 눈데 띄게 개선이 되었다.
8. 다음에 할 일
30시간 정도 걸리는 100% 학습을 한 뒤에 테스트를 해보자.
얼마나 답변의 퀄리티가 올라갔을지 기대가 된다.
그리고 매번 할 때마다 학습 결과물을 덥어 씌기 하고 있는데 해당 내용도 증분으로 저장하는 방식으로 바꿔봐야겠다.
- 끝 -