LLM을 medical text에 활용해보면서 느낀점 및 정리
요즘 Large Language Model (LLM) 모델의 인기가 엄청나다. 주로 유전체 정보와 환자의 영상이미지, 병리이미지 등을 다루다가, 이제는 pathology 및 radiology report까지도 다루게 됐다. 모든 연구자들은 빠르게 아무도 안해본 데이터를 활용해서 새로운 결과를 만들어 좋은 저널페이퍼를 출간하고 싶은 법..
나도 텍스트 데이터에 전혀 관심이 없다가 이번에 LLM을 활용해보면서 든 생각들을 정리해보았다.
필요한 GPU 메모리는 어느정도인가?
현재 내가 쓰고있는 GPU는 A6000 * 8개짜리로, 각 gpu는 대략 48기가의 용량을 갖는다.
내 경험상, 이 정도의 서버 스팩이면 7B 사이즈 정도의 텍스트는 충분히 처리할 수 있었다.
대략 7,000 ~ 12,000 개 정도로 된 input text를 활용하여, 원하는 정답을 맞추게끔 수행하는 task를 문제 없이 수행할 수 있었다.
구글링을 조금 해보니, 필요한 GPU를 추정하는 방법을 찾을 수 있었다.
M: GPU 메모리 (기가바이트 단위)
P: 모델의 매개변수 수
4B: 매개변수당 4바이트 사용
Q: 모델 로딩을 위한 비트 수 (예: 16비트 또는 32비트)
1.2: 20% 오버헤드 계산
따라서 7B 모델을 계산한다고 할 때,
7*4B * 1.2 = 대략 33.6GB가 필요하다는 결과가 나온다.
개인적으로, 2B 모델은 거의 동작을 못하는 것 같다.
최근 Gemma 2b가 어느정도 동작을 잘 한다고 기사도 나오고했지만,
직접 써보면 한숨이 나온다.
Quantization을 하는 한이 있더라도, 더 큰 모델을 활용하는 편이 2B보다 훨씬 좋은 것 같다.
Zero-shot
Zero-shot learning은 모델이 학습 과정에서 전혀 보지 못한 Task에 대해서
새롭게 추론을 수행하는 것을 의미한다.
즉, Prompt에 어떤 예시를 주지 않고, 학습하지도 않은 상황에서주어진 문제를 해결할 수 있는 방법입니다.
Classification:
Question: 다음 문장의 감정을 "긍정", "부정", "중립" 중 하나로 분류하세요.
Input: 오늘 날씨가 정말 좋아서 기분이 상쾌해요.
Output: 긍정
Text generation:
Question: 다음 질문에 대해 간단히 답변하세요.
Input: 광합성의 주요 원료는 무엇인가요?
Output: 광합성의 주요 원료는 이산화탄소(CO2)와 물(H2O)입니다.
Few-shot
Few-shot learning은 모델에게 적은 수 (보통 2~5개)의 예시만을 제공하여
새로운 태스크를 수행하게 하는 방법.
모델에게 몇 가지 예시를 보여주어 태스크의 패턴을 파악하게 하여,
모델은 유사한 패턴을 가진 새로운 입력에 대해서도 적절한 출력을 생성한다.
하지만, 경험상 medical domain의 context와, 어려운 사고 및 추론이 필요한 task에 대해서는
객관식으로 주어진 zero-shot, few-shot에서 성능이 매우 좋지 않음.
최근 JAMIA 라는 좋은 저널에서 나온 페이퍼도, 대략 AUROC 0.70~0.80 정도의 성능을 보임..
(심지어 medical data로 학습된 모델도 마찬가지)
Prompt engineering
이는 모델에게 우리가 원하는 더 좋은 출력을 얻기 위해 입력 (프롬프트)을 최적화하는 과정이다.
쉽게 말하면, 질문을 할 때 더 많은 정보를 주거나, 더 명확하게 질문하거나
원하는걸 더 명확하게 해서 모델에게 쿼리를 날려주는 것이다.
- 모델의 성능 최적화
- 특정 작업에 맞는 출력 유도
- 모델의 편향 및 오류 최소화
주요 Prompt Engineering 기법
- Role Prompting:
모델에게 특정 역할을 부여합니다.
예: "당신은 경험 많은 의사입니다. 다음 증상을 바탕으로 가능한 진단을 제시해주세요."
Chain-of-Thought Prompting:
모델에게 단계별 추론 과정을 요구합니다.
예: "다음 문제를 해결하세요. 각 단계를 자세히 설명해주세요."
Few-Shot Prompting:
몇 가지 예시를 제공하여 모델의 이해를 돕습니다.
예: "다음은 의학 용어를 일반인이 이해하기 쉬운 말로 바꾸는 예시입니다. 이를 참고하여 마지막 용어를 설명해주세요."
Self-Consistency:
여러 번의 응답을 생성하고 가장 일관된 답변을 선택합니다.
예: "이 질문에 대해 5가지 다른 방식으로 답변해주세요. 그 중 가장 일관되고 정확한 답변을 선택하겠습니다."
Meta-Language Prompting:
프롬프트 자체에 대한 지시를 포함합니다.
예: "다음 질문에 답하기 전에, 질문의 의도를 명확히 하고 필요한 추가 정보가 있는지 확인해주세요."
Fine-tunning
대규모 LLM 모델을 처음부터 Fine-tunning 하는 것은 사실상 불가능하기에,
우리는 보통 LoRA (Low-Rank Adaptation) 를 활용해서,
기존의 pre-trained model의 weights를 완벽하게 freezing 하여 보존한 상태로
우리가 원하는 task를 예측할 수 있도록 transformer block의 일부 추가적인 weight를 부여하여 학습해준다.
저는 주로 medical data를 다루기 때문에,
Gemma, Llama 같은 모델보단, MedAlpaca처럼 medical domain의 backbone을 활용했을 때
더 좋은 performance를 얻었다.
결론
제목은 거창했지만, 결론적으로 내가 정리하고 싶은 내용은
- 48G 정도의 GPU로 7B 모델 학습이 충분했음
- Prompt engineering이 굉장히 중요함.
처음엔 ChatGPT에게 물어보면서 좋은 question을 받아놓고,
차후에 해당 context의 전문가와 토론하면서 question을 만들면서 성능을 높힐 수 있음
- 어려운 도메인에서의 task는 7B의 pretrained model로는 fine-tunning 없이는 쉽지 않음
zero-shot은 어렵고, 좋은 예를 제시해준 few-shot도 마찬가지
- 결국 fine-tunning이 필요하다
하지만 text generation으로 문제를 정의하느냐, 객관식 문제로 보기를 제시하느냐 등
어떻게 이 문제를 접근해서 풀게끔 할 지 다양한 토론이 필요함