Chat GPT basic

프로젝트에서 Chat GPT를 사용할 때 필요한 내용들을 공부하고 정리해보았다.

 

LLM (Large Language Model)
Text Prediction Model : 이전에 들어왔던 텍스트(데이터)를 기반으로 어느 것이 적절한 지 예측하여  데이터를 생성함. 확률 분포에 따라 샘플링 하는 방식으로 작동함.

Token
자연어 처리에 있어 given text를 token화 하여, 이를 기반으로 현재의 맥락을 예측하는 것이 기본 작동 골자이다. 그래서 주어진 token을 얼마나 처리할 수 있는가 가 성능에 매우 중요한 영향을 미친다.

*Hallucination : 생성형 언어 모델이 올바르지 않은 결과를 마치 그럴듯하게 답변하는 경우. 자체 생성형에서 이런 것을 막기는 어렵고 후처리를 통해 제거하는 것이 현재의 개발 흐름이다.
Repeatability : 한 번 말했던 것을 번복하지 않고 동일한 답변을 내놓는 것. 대부분 hallucination에 대해 올바른 답을 요구하면 다른 답변을 주는 경우가 있다. 이런 경우는 repeatability에 부합하지 않는 것이다.

현재까지 ChatGPT를 이용하여 원하는 결과를 가지려면 hallucination을 잘 피해 여러 번의 input을 넣고, 자신이 알고리즘과 step을 잘 알고 있어야 수월하게 가능하다.

Prompt
이전에 들어갔던 모든 token set으로 답변을 생성하기 위한 기반 정보가 된다. 보통 답변을 위해 기본적인 응답 형태를 유도하는 system prompt는 약 1700개로 구성되어 있다.
따라서 모델의 성능과 관련없이 원하는 결과를 얻어내는데 (챗 봇, 질문 및 응답 등)는 프롬프트가 가장 중요한 역할을 한다.
특히 이런 데이터 모델을 학습시킬 때 prompt(demonstration)의 순서, 내용 등 모든 것이 결과에 큰 영향을 미친다.

* Reasoning : 어떤 문제에 대해 단계를 나누어 예시를 주면 원하는 결과가 나오는 경우. (Chain of Thought, CoT) 예를 들어 예전 버전에서는 물어볼 때 'Let's think step by step' 을 넣으면 성능이 올라갔다. (Zero-Shot CoT)

현재 산업의 기류는 데이터 셋을 학습시켜 원하는 결과를 얻는 방식으로 가고 있으며, 이 때 사용가능한 범위가 한정적인지에 따라 대용량, 경량이 갈리게 된다.


Prompt engineering
- Write clear instruction
디테일을 포함하여 질문하여야 더 좋은 답변을 얻을 수 있다. Delimiter (quote 등) 를 사용하여 어떤 형식을 만들어서 질문하는 것도 좋다. 그리고 CoT와 비슷한 맥락으로 step을 명시하고 예제를 제공하면 더 좋다. 그리고 답변을 제한하는 것도 필요하다.

*System : 미리 입력된 prompt, user : 유저가 입력한 prompt, assistant : 모델의 답변 prompt

모델은 system / user의 prompt를 조합하여 답변을 내므로 system을 잘 설정해야 한다.

- Provide reference text
Retrieval - Augmented Generation (RAG)
prompt engineering으로는 전문적인 지식 등을 답변할 수 없다. 따라서 적절한 내용을 검색하고, 그 결과를 불러와 답변을 생성하는데 사용하는 것이다.
이는 retriever(검색기), generator(생성기) 로 구성되며 검색기가 관련된 정보를 검색하고, 해당 내용을 기반으로 생성기가 답변을 생성하게 된다.

특정 분야의 전문 지식에 적용하기 위해서는 해당 기술이 반드시 필요하다. 이를 통해 정확도 향상과 외부 정보 접속에 의한 지식 업데이트 등의 이점을 가질 수 있다.
생성기는 LLM에 가까우므로 만들기 힘들고, 검색기를 특정 분야의 지식에 학습시켜 사용시키는 것이 일반적이다.

- Use external tools
Embedding
System prompt로 대용량의 정보를 넣어야 정확도가 올라가므로 해당 정보들을 다차원의 벡터로 치환하여 저장해놓는 것이다. (또한 대용량 정보를 넣으면 input token이 올라가므로 가격이 올라감)

이를 적용하는 방법은 전체 데이터를 token화하고 다차원 벡터로 연결하여(판다스 사용) DB를 구축하면 된다. 이후 입력된 질문에 대해 가장 가까운 벡터 거리(distance - relatedness)의 embedding을 일정 개수 가져오면, 모델 자체가 이를 참고하여 답변을 할 수 있다.

*Nearest Neighbor search : 특정 분야에 대해 가장 가까운 것을 서칭해서 저장하는 것. 특정 개수를 선택하면 KNNS가 된다.

결국 모든 정보를 모두 system prompt로 넣어놓을 수 없으므로 해당 정보를 따로 벡터형식의 DB로 구성하는 것이 작업의 흐름이 된다.

- Give the model time to think
바로 답변하지 않고 확인하는 과정을 추가하면 좀 더 정확한 결과를 얻을 수 있다. 이 역시 step by step을 활용하거나, 지난 prompt를 서치하는 과정이 있다면 더 좋다.

- Split complex task into subtasks
이것 역시 step을 나누어 성능을 향샹 시키는 방법이 된다.


ChatGPT API - Safety Check
부적절한 대답을 하는 경우, 저작권, 차별 등의 답변을 하는 것을 막아야 한다. 이는 chatGPT API에서 moderation을 통해 가능하며, 이는 분류기 처럼 input text에 대해 적절성을 판단해 분류해주는 방식으로 작동한다. (11개의 category로 구성됨)

Fine tuning
기존의 모델을 원하는 타겟 데이터에 맞춰서 추가로 훈련시켜 전체적인 퍼포먼스는 떨어지더라도 해당 분야에서 정확도를 올리는 과정. 데이터가 부족한 협소한 분야, 혹은 기존 모델을 특정 작업에 한정해서 사용하려고 할 때 많이 사용함.

모델을 수정하고 특정 파라미터를 바꾸거나 학습률을 바꿔 weight를 재학습 시키는 방식을 사용한다. 그러나 GPT 모델의 파라미터가 수백만 개가 넘어가기 때문에 실제 투입된 리소스에 비해 원하는 답변이 더 잘나오지 않고, 일반적인 성능은 떨어지는 경우가 많다. (튜닝은 비싸고 복잡한 작업 - 모델의 크기가 커질 수록 가격이 더 올라감)

그러나 prompting에 비해 높은 퀄리티의 결과를 얻을 수 있고, 적은 입력 만으로도 원하는 결과를 얻을 수 있다. 또한 입력해야 하는 데이터가 몇 만개가 넘어간다면 prompt로 입력하는 것보다 트레이닝을 하는 것이 더 좋을 수 있다. (API token 입력이 적어지므로 금액적으로 더 효율적일 수 있다)
또한 사내 대외비 데이터 자체를 제공하여 학습시키는 것 역시도 리스크가 큰 부분이다. 따라서 클라우드 서버 형태로 데이터를 제공하는 방식을 사용한다. (단, 개인 단위에서 이런 작업을 하기는 쉽지 않음)

embedding : data를 벡터형태로 바꾸어 사용.

활용하는 방법(scikit-learn)
ML : 보유한 학습 데이터를 기반으로 접근 방식을 결정. 이 데이터의 유형에 따라 discrete label이 존재하는 경우(classification) / continuous label이 존재할 때(regression) / label이 없는 경우 로 분류할 수 있다. (clustering/embedding/dimension reduction) 이 때 label이 존재하는 경우는 모두 supervised learning이라 한다. (해당 데이터가 옳은지 그른지 알려주는 역할을 하므로 supervised)

- classification : 주어진 데이터 분포(학습 데이터)- with discrete label 영역에서 레이블에 따라 decision boundary를 생성하고, 새로운 데이터가 추가되었을 때 이를 어디로 분류할 지 결정하는 문제
- regression : 연속적인 입력데이터(continuous label)에 대해 fitting 되는 함수를 예측. 새로운 입력에 대해서도 이 함수를 기반으로 값을 예측할 수 있음.
-clustering : unsupervised data set.( 데이터의 분류가 이루어지지 않고 그냥 흩뿌려진 형태로 주어짐-no label) 에서 입력 데이터에 대해 패턴/군집을 계산하는 문제.

주어진 문장들의 feature vector = embedding으로 변경. 이에 estimation algorithm을 선택하여 학습-fitting (상기의 세 방법 중 선택)
이후 새로운 데이터(문장)이 들어오면 다시 embedding으로 바꾸고 예측값을 출력하는 것이 작업의 흐름이 된다.


사용한 데이터를 임베딩 한 후에 이들을 평가하는 방법.
1. cross-validation : train / test data를 분류하고 구간을 분리해서 모델을 실행시킨 값의 평균으로 모델을 평가하는 방법. 새로운 데이터가 들어왔을 때 모델이 어떤 판단을 할 지 예측하고 평가하는데 사용할 수 있음. 다만 데이터가 많아지는 시점에서는 굳이 필요하지 않을 수 있지만, 데이터가 적을 때는 매우 효과적이다.

2. variance / bias, Overfit / underfit
데이터를 기반으로 예측 모델을 형성할 때 너무 적은 파라미터를 써도, 너무 많은 파라미터를 써도 정확한 결과가 나오지 않는다. (flexibility가 없거나 너무 sensitive하게 된다)
- underfitting : 모델이 너무 간단해서 high bias & low variance를 가진다. 따라서 training error, test error가 매우 크다.
- overfitting : 모델이 너무 복잡하고 training set에 대해서만 fitting 되어 low bias & high variance를 가진다. 이 경우 해당 학습 데이터에 대해서는 매우 잘 맞지만, 다른 입력 값에 대해서는 좋지 않은 결과를 낸다. low training error, high test error를 가진다.
- variance : 데이터 변화에 대해 모델이 변경하는 정도. 이는 적은 것이 좋음(노이즈가 있어도 모델이 robust하게 유지되는가) 이 값이 높으면 overfit & low bias, 값이 낮으면 underfit & high bias이다. (일반적으로 robust하면 특정 함수 형태에 고정되어 있게 되므로 bias가 크게 된다.)
- bias : 모델이 특정한 형태에 bias 되어 있는가. 이 역시도 적은 것이 좋다.

KNN(Kth nearest neighbor classifier)
데이터마다 label이 붙어 있고, 새로운 입력 데이터에 대해 거리가 가장 가까운 데이터 k개를 통해 판단하는 것. 이 경우 학습을 하는 것은 아니고 그냥 학습 데이터(임베딩)에 대해 거리가 얼마나 되는지 계산하여 입력 데이터를 분류하는 분류기와 비슷한 형태이다.

이 때 가장 가까운 k개를 선택하는 것이 중요한데, 너무 작으면 노이즈를 걸러낼 수 없고, 너무 많으면 변화에 둔감하고, 다른 클래스가 포함될 수도 있다. (k가 너무 작은 경우 : overfitting, k가 너무 큰 경우 : underfitting) 이를 기반으로 학습데이터와 k에 대해 decision area를 정의할 수 있다.

일반적으로 variance & bias가 trade-off 관계이므로 test error가 줄어들다가 증가하기 시작하는 부분에서 fitting을 멈추는 것이 좋다. 이 것을 early stop이라 한다. (training error는 더 줄일 수 있지만 미리 정지)

KNN에서 중요한 것은 차원이 올라갈 수록 샘플들 끼리 사이의 거리가 멀어진다는 것이다. 따라서 서치해야 할 영역이 매우 넓어지기 때문에 feature vector가 늘어날 수록 거리 기반의 서칭은 제대로 작동하지 않는 경우가 많다. 이를 차원의 저주 (curse of dimension) 이라 한다.
이는 moderazation, regularization 등으로 해결할 수 있다.

Scikit - Learn
python library. Estimator 라는 클래스에 배운 여러 모델이 포함됨. 이를 fit() 으로 데이터에 모델을 fitting을 할 수 있다.그리고 새로운 데이터에 대해 predict()를 통해 결과 값을 예측할 수 있다.
이를 사용하기 위해 데이터를 걸러내고 정제하는 과정이 필요하다. (null 값 제거, normalization 등) 이런 전처리 작업은 transformer class 내부에 imputer, preprocessing 등으로 사용할 수 있다.
Classification method - F1 score
label이 두 개인 경우에서 디자인 된 평가 문제. true/false는 실제 데이터에 달려 있는 label. negative/positive는 우리 모델이 판단한 결과 값.

precision은 예측 모델이 positive라고 출력한 것이 얼마나 정확한가? (모델 판단 true /모델 전체 판단) Recall은 해당 모델이 실제 제공한 true 값을 얼마나 잘 캐치하는가?(모델 판단 true/전체 positive)를 나타낸다. F1 score는 precision과 recall의 조합평균으로 구성된다. (각각의 의미와 영역의 위치를 외우기)

label 두 개인 경우에는 그냥 사용하면 되고(이를 위해 디자인 되었으므로) 3 개 이상일 경우에는 선택할 수 있는 다양한 방법이 있다. (macro/micro/weighted 등등.... 퀴즈 안나옴)

Regression
model이 얼마나 잘 fit되어 있는지 MSE(mean square error)로 측정할 수 있다.
이는 MSE나 R2 score를 이용하여 fitting 정도를 측정할 수 있다.

clustering은 label이 없어 점수화 하기가 쉽지 않기 때문에 분포도를 그림으로 그려 사람이 판단하는 경우가 많다. (정량적 판단보다는 정성적 판단을 사용 - 주로 DBSCAN 을 사용)

Dimension reduction
unsupervised 에서 입력 차원을 줄여 curse of dimensionality를 보완하는 방법.
- Principle component analysis(PCA) : n dimension을 k dimension으로 감소시키는데 사용하는 것.
- t-SNE : 마찬가지로 dimension을 줄이는데 사용함. 주로 visualization 하는데 사용. 단, label에 따라 위치를 변환하여 표현하기 때문에 임베딩의 오리지널 값을 가진다고 보기 어렵다. 따라서 ML은 보통 PCA를 사용하고 tsne는 그림으로 표현하는데 사용한다.


data에 label이 제공되면 supervised. discrete label - classification / continuous label - regression / no label - clustering, embedding, dimension reduction.
- classification : decision boundary를 나누어 입력 데이터의 위치를 기반으로 출력을 결정하게 됨.
- regression : 입력 데이터에 대한 연속적인 출력을 예측. 함수를 형성하여 입력에 대한 출력을 형성. continuous label = y 값 / input x에 대해 y를 결정해야 함.
- clustering : label이 없는 데이터를 몇 개의 집단으로 군집화.

Dimension reduction
PCA(principal component analysis) : label이 없을 때 작동하는 dimension reduction 방법.
T-SNE : 수백 dimension을 가지는 높은 차원의 데이터를 2, 3차원으로 변환하여 visualization하는데 사용하는 방법.

Cross validation(교차검증)
데이터가 많지 않을 때 학습데이터를 train set과 test set으로 분리하여 학습과 검증을 하는 방법. 이 때 전체 데이터 셋의 train/test의 portion을 바꿔가면서 하여 오류의 평균을 내는 방식으로 사용한다. (5-fold CV error라면 겹치지 않게 20%씩을 test set으로 설정하고, 나머지로 train을 하는 방식. 이렇게 하면 결국 전체 데이터에 대해 test를 한 번씩 해보게 되므로 해당 데이터들이 대표성을 띈다고 생각할 수 있다) 이렇게 하면 특정 데이터셋에 편중되는 것들을 방지할 수 있다. 만약 데이터 중에 다른 방식으로 사용되어야 할 경우(validation 등) 일반적으로 train set의 일부를 떼서 사용한다. (왜냐하면 테스트 셋은 전체 데이터를 한 번씩 검증해야 하므로)

- Variance : 데이터 변화에 대한 모델의 변화정도. 낮은 것이 좋다. 왜냐하면 측정 데이터에 noise가 섞일 수 있는데, 이에 대해 너무 흔들리지 않고 robust하게 작동해야 하기 때문이다.
- Bias : 모델이 특정한 데이터 형태에 고정되어 있는 정도. 마찬가지로 낮은 것이 좋다. 왜냐하면 데이터가 변화해도 다른 결과를 내놓지 않고 같은 결과만 낼 수 있기 때문이다.

그러나 이 둘은 trade-off 관계이므로 적절한 값을 설정해야 한다.

- Overfitting : 너무 많은 파라미터를 가져 학습데이터에 지나치게 fitting되어 high variance, low bias를 가지게 됨. 이는 데이터의 noise도 모두 학습하여 다른 데이터를 넣었을 때 원하는 결과를 내놓지 못한다. (학습 데이터의 loss는 매우 낮아지지만, 다른 입력에 대해서는 loss가 오히려 증가할 수 있다.) 따라서 이를 방지하기 위해서 Early stop을 해야 한다.
- Underfitting : 너무 적은 파라미터를 가져 input에 대해 적절한 output을 내놓지 못한다. low variance, high bias. 결국 학습 데이터 셋에 대해서도 원하는 결과를 얻지 못하는 것이다. (학습 데이터의 loss도 떨어지지 않음)

이들의 해결방법
- underfitting : 모델이 너무 간단하므로 마찬가지로 데이터의 차원을 줄이거나 데이터 샘플을 줄여 이 모델에 맞도록 하는 방법이 있다. 또는 모델을 데이터에 적합하도록 사전 지식을 바탕으로 더 많은 파라미터를 추가하여 더 복잡한 모델을 만들면 된다.
- overfitting : 데이터를 설명하는 feature vector를 늘리고, 데이터 샘플을 늘려보는 방법을 생각해볼 수 있다. (데이터가 복잡해지면, 복잡한 모델에 적합). 그리고 모델의 복잡도를 줄이기 위해 파라미터를 줄이고 여러 regularization을 주어보는 방법이 있다. (모델의 과도 학습을 막기 위해 어느 정도 제약사항을 준다. ) 그리고 테스트 셋이 신뢰할 만 하다면, early stop으로 과도한 학습을 막는 것도 방법이 된다.

K-NN(Nearest Neighbor Classifier)
supervised, discrete label을 가지는 classification 문제를 해결하는 방법. 해당 데이터와 가장 가까운 k개의 데이터를 고려하여 가장 많은 것으로 고려하겠다는 간단한 방법. k가 작으면 overfitting이 되고,(input data의 작은 변화에 민감 - high variance) k가 커지면 underfitting이 된다. (여러 개를 고려하므로 입력 데이터의 변화가 큰 변화를 가져오지 못한다 - low variance)

해당 방법은 dimension이 낮을 때만 잘 작동하며, 차원이 커지면 거리 기반 연산이 제대로 작동하지 않으므로 큰 차원에서는 사용하기 어렵다.

전체 데이터가 positive와 negative로 구분되고, 모델이 예측한 positive와 negative가 존재한다. 이 때 모델이 올바르게 예측할 경우(positive일 때 positive, negative일 때 negative)이를 true pos/neg 라 하고 (TP, TN), 모델의 예측이 틀렸을 경우 (positive라 했는데 negative 혹은 vice versa) 이를 false pos/neg 라 한다. 이 결과를 기반으로 모델의 예측이 얼마나 정확한지, 그리고 positive를 얼마나 잘 걸러내는지를 판별하는 것이 아래의 feature이다.

- Precision = TP / (FP + TP). 모델이 true라고 예측한 것 중에 실제 true인 값. 모델의 positive 판단의 정확도.

- Recall = TP / (FN + TP). 모델이 전체 positive 중에 얼마만큼을 positive로 판별했는지를 나타낸다.
F1 score는 이 둘의 조합평균으로 계산한다.
Class(Label) imbalance
있는 데이터만 있는 것. 예를 들어 특정 class의 sample만 많이 모이고, 나머지 class의 sample이 거의 안나오는 문제. 이렇게 되면 학습한 모델의 정확도는 크지만, 다른 클래스를 고려하지 않으므로 의미가 없어진다.
따라서 imbalance를 해결하기 위해 적은 데이터에 가중치를 주는 class weight 방법이 있다. 그러나 imbalance가 크면 효과가 떨어지고 overfitting 될 수도 있다.
따라서 그냥 작은 data sample에 큰 data sample을 꺼내 오는 방법이 더 많이 사용된다. 이를 under sampling 이라 하고, bagging 기법으로 여러 학습기를 만들고 voting 방법을 사용하는 것이 좋다.

댓글

이 블로그의 인기 게시물

IIKH Class from Timothy Budd's introduction to OOP

Compiler 9 - Efficient Code generation

Software Engineering 10 - V&V, SOLID principle