728x90

왜 할루시네이션이 발생하는지 알려면 언제 발생하는지도 알아야한다.

What is Hallucination?

사실이나 맥락적 논리(맥락에 안맞는 말)에서 벗어나는 LLM의 Output.

할루시네이션은 사소한 불일치부터 완전히 조작되거나 모순된 Output이 될 수 있다.

오늘은 4가지 종류의 할루시네이션에 대해 살펴보자.

1. 문장 모순 (Sentence Contradiction)

LLM이 이전 문장과 모순되는 문장을 생성하는 경우.

“오늘 날씨가 참 맑네요. 근데 오늘 날씨가 너무 안좋아요”

2. 프롬프트 모순 (Prompt Contradiction)

생성된 문장이 그것을 생성하는데 사용된 Prompt와 모순되는 경우

음식점에 대해 좋은 리뷰를 작성해달라고 요청했을때 : “음식이 다 식어있고 맛이 너무 없어요”

3. 사실적 모순 / 오류 (Factual Contradiction / Error)

생성된 문장이 사실과 다른 내용을 포함한 경우

“이순신 대통령은 대한민국 1대 대통령입니다”

4. 무관한 오류 (Non-sensical)

LLM이 실제로는 존재하지 않는 무언가를 집어넣거나 질문과 전혀 관련 없는 내용을 이야기 할때.

“파리는 프랑스의 수도에요. 그리고 파리는 유명한 가수의 이름이에요”

Why Hallucinate?

LLM의 결과 도출방식이 사실상 블랙박스(안을 볼수가 없음 / 봐도 이해 못함)기 때문에 정확히 어떤 이유에서 할루시네이션이 발생했다고 말하기는 어렵지만 몇 가지 일반적인 원인이 있다.

1. 데이터의 품질(Data Quality)

LLM은 노이즈, 오류, 편견, 불일치가 포함된 데이터로 학습하는 경우 예를 들어, 위키피디아나 레딧을 사용했기 때문이다. 레딧이나 위키피디아의 내용을 100% 신뢰할 수는 없다.

데이터가 100% 정확하더라도 콘텐츠 생성에 필요한 모든 주제 / 도메인을 다루지 않을 수 있다.

따라서, 데이터의 정확성 / 관련성을 검증하지 못한채 데이터를 일반화하는 경우가 발생하고 때로는 이러한 방식이 잘못되는 경우가 발생한다.

물론, LLM의 추론(Reasoning) 능력이 향상됨에 따라 환각이 감소하는 경향이 있다.

2. 생성 방식 (Generation Method)

LLM은 텍스트를 생성하기 위해 다양한 방법과 목표를 사용한다. 예를 들어, Beam Search, Sampling, Maximum Likelihood Estimation, Reinforcement Learning)

이러한 방법과 목표는 유창함과 다양성, 일관성과 창의성, 정확성과 참신함 사이의 상충관계(Trade-Off)를 초래할 수 있다.

가령, Beam Search는 높은 확률이지만 포괄적인(Generic) 단어를 낮은 확률이지만 구체적인(Specific)보다 선호한다.

3. 입력 맥락 (Input Context)

여기서 Context란 Input Prompt로 모델에 제공되는 정보를 의미한다.

Context는 모델이 관련성 있고 정확한 출력을 생성하도록 안내하는데 도움이 될 수 있지만,

명확하지 않거나 일관성이 없거나 모순되면 모델을 혼동하거나 오해하게 할 수 있다.

예를 들어, LLM 챗봇에 “고양이가 영어를 할 수 있나요?” 라고 물으면 “아니요, 좀 앉아서 쉬실래요?”라는 답변을 받을것이다. 하지만 만약 내가 가필드 만화 시리즈에 대해 이야기 하고 있다는 Context를 포함했다면 LLM은 “네, 고양이는 영어를 할 수 있고 저 고양이는 라자냐를 두번째로 달라고 할거같아요~” 라는 답변을 받을 것 이다.

Context는 중요하고 학술 에세이나 창의적인 글쓰기 연습에 필요한 텍스트를 찾고 있다고 말하지 않으면 해당 텍스트가 해당 맥락 내에서 응답할것이라 기대할 수 없다.

How can we MITIGATE Hallucination

1. 명확하고 구체적인 프롬프트 제공 (Clear & Specific Prompt)

입력 프롬프트가 더 정확하고 상세할수록 LLM이 관련성이 높고 (가장 중요한) 정확한 출력을 생성할 가능성이 높아진다.

예를 들어, “2차 세계 대전에 무슨 일이 일어났나요?” 라는 질문 대신에

“갈등의 주요 원인에 연루된 주요 국가를 포함하여 제 2차 세계 대전의 주요 사건을 요약할 수 있습니까?” 라고 말할 수 있다.

2. 적극적인 완화 전략 (Active Mitigation)

LLM이 문장을 생성할때 관여하는 hyper parameter를 조정하는 방식이다.

이에 대한 좋은 예는 출력의 Randomness(임의성)을 제어할 수 있는 Temperature 매개변수이다.

Temperature가 낮을수록 더 보수적이고 집중된 답변을 생성하고 Temperature가 높을수록 더 다양하고 창의적인 반응이 생성된다.

다만, Temperature가 높을수록 환각이 일어날 확률이 높아진다.

3. 멀티샷 프롬프트 (Multi-shot Prompt)

하나의 Prompt만 제공하는 Single-shot Prompt와 달리 멀티샷은 LLM에 원하는 출력 형식이나 컨텍스트에 대한 여러 예를 제공해서 모델의 답변을 개선한다.

여러 가지 예를 통해 LLM을 제시해서 패턴이나 context를 보다 효과적으로 인식하는데 도움이 되고 이는

특정 출력 형식이 필요한 작업에 특히 유용하다.

예를 들어, 특정 스타일로 코드를 작성하고, 시를 쓰고, 질문에 특정한 형태로 답을 하는 경우이다.

Reference

Why Large Language Models Hallucinate

'인공지능 > LLM' 카테고리의 다른 글

AGI로 가는 길에 LLM의 한계와 강화학습의 한계  (3) 2024.11.02
할루시네이션 발생 원인  (0) 2024.11.02
LLM의 Risk  (0) 2024.11.02
Knowledge Distillation - LLM  (0) 2024.03.17
RAG란?  (0) 2024.03.17
728x90

LLM의 한계

Scaling is not enough

현재 LLM의 규모만 더 키우면 결국에 인간과 비슷한 수준의 AI가 탄생할 것이라는 주장을 단 한 순간도 믿어본 적이 없다 얀 르쿤

1. 현재 LLM은 토큰화가 필수

  • 토큰화는 discrete하고 low-dimensional인 텍스트 데이터에는 잘 적용된다
  • 하지만 continuous 하고 high-dimensional 시그널인 비디오에는 접목되지 않는다.

2. LLM 구조상 한정적인 추론만 가능

  • Abstract latent variables를 포함하지 않는 모델의 특성상→ 사람처럼 고맥락의 행동을 할 수 없다고 주장(과거에 대한 기억이 없으니까)(2) 그리고 그 바탕으로 optimal course of action을 찾아 수행할 여지가 없음
  • (1) perception에 대한 다양하고 다채로운 해석을
  • → short-term memory에 해당하는 부분이 없어서 한정적인 정보 만으로 다음 상황을 예측해야함

강화 학습의 한계

Reward is not enough

강화학습 방식을 사용하려면 모델에게 간단한 작업만 학습시킨다 해도 방대한 데이터가 필요하다. 나는 그런 방식은 성공 가능성이 없다고 생각한다. 얀 르쿤

1. 스칼라 리워드로는 한정적인 정보만 제공되고, 이는 ‘과다한’ 실패로 이어진다

숫자로 정의되는 리워드들은 한정적이다 → 세상은 숫자만으로는 표현 불가능한데 명확히 판단되지 않는 상황이 너무 많다

  • Intrinsic cost module이 환경 그 자체가 되고, 그 말은 unknown function 이라는 말이다.
  • Model-free RL은 인간/동물 대비 대단히 비효율적이다 → 모든 경우의 수를 다 경험해야한다
  • Model-based는 그나마 낫지만 World Model을 훈련하기에는 reward로는 부족하다

결론

결국 AGI를 만들기 위해서는 뇌 구조도 인간과 유사해야하고 훈련 방식도 인간과 유사해야한다.

“위와 같은 얀 르쿤의 아이디어가 딥러닝 커뮤니티에서 나온 것은 처음이다” ”LLM은 실제로 중요한 부분은 세계에 대한 내부 모델과 기억력이 부족하다” Santa Fe 연구소, 멜라니 미셸

반대 입장

“르쿤의 제안에서 언어가 완전히 배제된 것은 이상하다; 우리는 LLM이 매우 효과적이며 수많은 인간의 지식을 활용한다는 사실을 알고 있다” ”인간이 무언가를 배울 때 직접적인 경험이 꼭 필요한 것은 아니다, 우리는 뜨거운 냄비를 직접 만지지 않더라도 그렇게 하지 말라는 말만 듣고 행동을 고칠 수 있으며 언어가 없다면 얀이 제안하는 이 세계모델을 어떻게 업데이트할 수 있겠는가? 구글 브레인, 나타샤 자크

Reference

[AI인사이트] AI계의 사대천왕 얀 르쿤! 딥러닝 외길만 40년을 걸어온 그가 이제 와서 지금의 연구가 잘못 됐다는데.. 과연 그가 제안하는 AGI(일반인공지능)로 가는 길은?

AGI로 가는 길에 LLM의 한계와 강화학습의 한계

'인공지능 > LLM' 카테고리의 다른 글

Why LLMs Hallucinate?  (1) 2024.11.02
할루시네이션 발생 원인  (0) 2024.11.02
LLM의 Risk  (0) 2024.11.02
Knowledge Distillation - LLM  (0) 2024.03.17
RAG란?  (0) 2024.03.17
728x90

원인

LLM이 다음 토큰이나 단어를 생성할 때 마다 그 단어가 합리적인 정답에서 벗어난 단어가 될 가능성이 있다.

그리고 이 오류가 각 단어마다 따로 발생할 수 있다고 가정하면 긴 문장을 만들수록 오류가 발생할 가능성이 커진다

즉, 토큰을 생성할때마다 올바른 정답의 집합에 머무를 확률이 기하급수적으로 낮아진다

실수할 가능성이 조금이라도 있으면 오류가 점점 더 커질 수 있다. 그리고 그 실수는 기하급수적으로 증가하며 오류가 쌓인다.

따라서, 문장이 길어질수록 엉뚱한 답(non-sensical)이 나올 확률도 기하급수적으로 높아진다.

질문

만약 훈련 데이터가 대부분 올바르면 자연스럽게 올바른 답변을 하지 않을까?

답변

그렇지 않다. “차원의 저주”라고 할 수 있다. 즉, 데이터의 차원이 증가할수록, 즉 feature(변수)의 수가 많아질수록 데이터 분석이나 모델 학습이 어려워지는 현상

이를 해결하려면 시스템이 다양한 질문에 답할 수 있도록 조정해야한다.

사람들이 자주 하는 질문은 비슷한 경우가 많다. 따라서, 수집된 데이터로 80%의 질문에는 답할 수 있다.

그리고 시스템을 finetune해서 모든 질문에 대해서 좋은 답변을 생성하도록 한다.

그런데 훈련중에 다루지 않는 막대한 양의 Prompt가 존재한다. 그리고 그 집합은 매우 크다.

가능한 모든 프롬프트 중에서 훈련에 사용된 프롬프트는 아주 적다.

전체 프롬프트 중에서 매우 적은 일부만 훈련에 사용된다.

따라서, 시스템은 사전 훈련되거나 FineTuning 된 프롬프트에서는 잘 작동한다.

하지만, 훈련되지 않은 막대한 양의 질문의 집합이 존재한다.

시스템이 아무리 훈련이 잘돼도 훈련되지 않은 프롬프트나 그런 형식의 프롬프트를 찾으면 시스템이 잘못된 답변을 생성할 수 있다. 그러면 엉뚱한 답변을 생성한다.

질문

인터넷에 없는 완전 새로운 prompt를 만드는게 가능한가? 쉬운가?

답변

프롬프트에 무작위로 생성된 문자나 기호를 넣는 방식이 있다. 이 방식을 사용하면 시스템은 혼란을 겪어 평소와 전혀 다른 방식으로 답변하게 된다.

이런 식으로 프롬프트에 변형을 주면 시스템이 원래 의도한 답변이 아닌 완전 다른 반응을 보이게 된다.

이는 시스템을 제약에서 벗어나게하는 방식으로 시스템의 한계를 명확하게 보여준다.

질문

문법적으로 올바른 문장을 사용해도 시스템을 무너뜨릴 수 있는가?

답변

그렇다. 영어로 문장을 작성한 뒤에 일부 단어를 동일한 의미를 가진 다른 언어로 치환하면 답변이 갑자기 바뀐다.

문제는 긴 문장이다. 사람들의 질문은 매우 긴 문장이고 대부분의 사람들이 물어보는 질문중 80% 정도만 시스템을 학습시킬 수 있다.

하지만, 긴 문장이 너무 많아서 모든 조건에 맞게 시스템을 학습시킬 수 없다.

결국 시스템은 일종의 Look Up Table이 될 수 밖에 없다.

→ 특정 입력 값에 대해 미리 계산된 결과 값을 저장해두는 데이터 테이블

하지만, 이는 추론하고 계획할 수 있는 시스템이 아니다.

원인

잘못된 학습 데이터

AR 방식의 토큰 생성

해결 방법

학습되지 않은 프롬프트에 대해서도 신뢰성 있는 대답 → 일반화 능력 필요 or 추론 능력 필요

그저 답을 생성하는 것 이상의 과정이 필요

'인공지능 > LLM' 카테고리의 다른 글

Why LLMs Hallucinate?  (1) 2024.11.02
AGI로 가는 길에 LLM의 한계와 강화학습의 한계  (3) 2024.11.02
LLM의 Risk  (0) 2024.11.02
Knowledge Distillation - LLM  (0) 2024.03.17
RAG란?  (0) 2024.03.17
728x90

LLM의 Risk는 총 4가지가 있다. Hallucination, Bias, Consent, Security.

오늘은 이러한 위험과 그 위험을 완화할 수 있는 전략을 알아보자

Risk 1 : Hallucination

LLM은 구문적(syntactic)으로 올바른 다음 단어를 예측한다.

즉, 사람의 질문을 이해해서 답을 생성하는 것이 아니다.

따라서, 듣기에는 그럴듯해보이지만 거짓말을 늘어놓는 경우가 발생한다.

이러한 잘못된 답변은 통계적 오류다.

예를 들어, “시 A, B, C를 쓴 사람이 누구야?” 라는 질문이 들어왔고 데이터 소스에 작품 A는 작가 X가, 작품 B는 작가 X가, 작품 C는 작가 Z가 작성했다라는 정보가 있다 하자.

이 경우 훈련 데이터에 상충되는 source가 있고 잘못된 답변을 생성하는 경우가 발생할 수 있다.

심지어 훈련 데이터에 불일치가 없더라도 통계적 오류가 발생할 수 있다.

이게 다 LLM이 의미를 이해하지 못하기 때문이다.

Strategy 1 : Explainability

Inline explainability를 제공할수도 있고 지식 그래프를 통해서 실제 데이터와 데이터 계보 및 출처를 제공하는 시스템을 LLM과 연동할 수 있다.

LLM이 방금 생성한 답변의 이유, 데이터의 출처 등..

LLM은 지식 그래프에서 제공한 답변에 대한 변형을 제공할 수 있다.

Risk 2 : Bias

시인에 대한 질문을 했을때 백인 | 남성 | 서유럽 시인만 나열되는 경우가 발생할 수 있다.

즉, 데이터가 편향되어있는 경우이다.

만약 조금 더 일반적인 경우를 원한다면 프롬프트에 “여성과 비서구 유럽인이 포함된 시인 목록을 알려줘”라고 해야 할 수 있다.

Strategy 2 : Culture and Audits

AI는 우리의 편견을 반영하는 훌륭한 거울이라 LLM에 문화를 다양하게 반영하려면 AI를 작업하는 팀도 다양한 배경과 분야에 걸친 인력이 필요하다.

AI 모델을 감사해서 이질적인 결과가 나오면 조직 문화를 바로잡을필요(?)가 있다.

사전 모델 배포와 사후 모델 배포를 감사한다.

Risk 3 : Consent

Curating 하는 데이터가 대표적인 데이터인지? 동의를 받고 수집되었는지? 저작권 문제는 없는지? 등을 살펴봐야한다.

위의 내용들은 찾기 쉬운 자료로 관리해야한다.

자주 LLM의 학습 데이터의 출처를 모르는 경우가 발생한다.

Strategy 3 : Accountability

AI 거버넌스 프로세스 확립, 기존 법률 및 규정 준수 확인, 사람들이 피드백을 통합할 수 있는 방법 제공해야 한다.

Risk 4 : Security

LLM은 모든 종류의 악의적인 작업에 사용 가능하다. 예를 들어 개인정보 유출, 피싱 범죄, 스팸, 사기 지원 등이 있다.

탈옥 : 해커들이 AI 모델로 원래 프로그램을 변경하거나 인종차별을 지지하고 사람들에게 불법적인 일을 하도록 제안하는 경우가 발생한다.

Indirect Prompt Injection : 제 3자가 웹사이트를 변경해서 숨겨진 데이터를 추가해서 AI의 동작을 변경하는 것이다.

따라서, AI에 의존하는 자동화는 사용자가 모르는 사이에 악의적인 지침을 보낼 수 있다.

Strategy 4 : Education

우리가 사용하는 기술의 강점과 약점을 알아야한다.

AI의 책임있는 큐레이션, 위험, 환경비용 및 기회 등에 대한 교육이 필요하다.

오늘날 일부 기술 회사는 LLM의 교육 데이터가 악의적으로 변조되지 않았다고 믿지만 사실은 Website를 사서 오염된 데이터로 채울 수 있고 충분한 예제로 데이터셋을 오염시킨다면 LLM의 동작과 출력에 영향을 미칠 수 있다.

Reference

Risks of Large Language Models (LLM)

'인공지능 > LLM' 카테고리의 다른 글

AGI로 가는 길에 LLM의 한계와 강화학습의 한계  (3) 2024.11.02
할루시네이션 발생 원인  (0) 2024.11.02
Knowledge Distillation - LLM  (0) 2024.03.17
RAG란?  (0) 2024.03.17
챗봇 구현 실습 (4) - 챗봇 구현  (0) 2024.03.17
728x90

Knowledge Distillation(KD)이란 더 크고 복잡한 모델(LLM)의 정보 혹은 지식을 더 작고 효율적인 모델(sLLM)에 전달(transfer)하는 기술입니다. KD의 목표는 LLM이 학습한 풍부한 표현(rich representation)을 sLLM에 전달해서 자원-효율적이면서 LLM과 비슷한 정확도를 갖게 하는것 입니다.

이를 적용하기 위해서 우선 teacher model(대규모 모델)을 먼저 훈련시킵니다. 이후 student model이 특정 Loss function을 통해 훈련합니다. 이 loss function은 단순히 훈련 데이터의 label 뿐만 아니라 teacher model이 생성한 soft output(probabilities)에도 기반합니다. 이러한 soft output은 hard 레이블보다 더 섬세한 이해를 제공하며, 다양한 class에 걸쳐 teacher model의 confidence를 전달한다.

학습 과정에서 temperature parameter를 활용해서 확률을 soften해서 분포(distribution)을 더 유익하고 student model이 학습하기 쉽게 만들어줍니다.

잘 알려진 teacher-student pair는 NLP 분야에서 BERT-DistillBERT가 있고 image classification 분야에서는 Resnet-50과 Mobile-Net이 있습니다.

실습 코드

import torch

import torch.nn.functional as F

def distillation_loss(student_logits, teacher_logits, targets, temperature):

    soft_loss = F.kl_div(F.log_softmax(student_logits / temperature, dim=1),

                         F.softmax(teacher_logits / temperature, dim=1),

                         reduction='batchmean') * (temperature ** 2)

    hard_loss = F.cross_entropy(student_logits, targets)

    return soft_loss + hard_loss

# Assuming teacher_model and student_model are defined and loaded

# Define temperature and alpha for balancing the loss components

temperature = 5.0

alpha = 0.5

# Compute teacher and student outputs

teacher_logits = teacher_model(input_data)

student_logits = student_model(input_data)

#
Compute distillation loss

loss = distillation_loss(student_logits, teacher_logits, 
                        targets, temperature)

# Backpropagate and update student model

loss.backward()

optimizer.step()

 

'인공지능 > LLM' 카테고리의 다른 글

할루시네이션 발생 원인  (0) 2024.11.02
LLM의 Risk  (0) 2024.11.02
RAG란?  (0) 2024.03.17
챗봇 구현 실습 (4) - 챗봇 구현  (0) 2024.03.17
챗봇 구현 실습 (3) - streamlit  (0) 2024.03.17
728x90

RAG (Retrieval-Augmented Generation)는 자연어 처리 분야에서 사용되는 한 기술로, 텍스트 생성을 위해 정보 검색과 기계 학습을 결합한 모델입니다. 이 모델은 주로 질문에 대한 답변을 생성하는 데 사용되며, 이를 위해 두 가지 주요 구성 요소를 활용합니다: 검색 엔진과 생성 모델.

  1. 검색 엔진 (Retrieval Component): RAG 모델의 첫 번째 단계는 주어진 질문에 관련된 문서나 데이터를 검색하는 것입니다. 이 검색 엔진은 데이터베이스나 인터넷에서 관련 정보를 찾아 이를 모델에 제공합니다. 이 검색 결과는 질문에 대한 답변을 생성하는 데 필요한 배경 지식을 제공합니다.
  2. 생성 모델 (Generation Component): 검색된 정보를 바탕으로, 생성 모델은 이를 통합하여 자연스러운 언어 형식의 답변을 생성합니다. 이 모델은 주로 트랜스포머 기반의 언어 모델을 사용하며, 검색된 내용과 질문을 입력으로 받아 답변을 생성합니다.

RAG 모델은 기존의 순수한 언어 모델보다 더 정확하고 상세한 정보를 제공할 수 있습니다. 왜냐하면 실시간으로 관련 데이터를 검색하고, 이를 바탕으로 답변을 생성하기 때문입니다. 이런 방식은 특히 대규모의 정적인 학습 데이터에만 의존하는 기존 모델들이 갖는 한계를 극복하고, 보다 다양하고 최신의 정보를 반영할 수 있게 해줍니다.

RAG는 OpenAI의 GPT 시리즈와 같은 순수 생성 모델과는 다르게 작동합니다. 이는 특히 복잡한 질문에 대해 더 정확하고 깊이 있는 답변을 생성하는 데 유용합니다. 예를 들어, 최신 뉴스 이벤트나 매우 특정한 주제에 대한 질문에 답변할 때 RAG 모델은 관련 데이터를 검색하여 더 정확하고 상세한 정보를 제공할 수 있습니다.

 

RAG 관련 자료

'인공지능 > LLM' 카테고리의 다른 글

LLM의 Risk  (0) 2024.11.02
Knowledge Distillation - LLM  (0) 2024.03.17
챗봇 구현 실습 (4) - 챗봇 구현  (0) 2024.03.17
챗봇 구현 실습 (3) - streamlit  (0) 2024.03.17
챗봇 구현 실습 (2) - FastAPI  (1) 2024.03.17
728x90

import

from fastapi import FastAPI
import pydantic
from pydantic import BaseModel
from typing import List
import openai
from openai import OpenAI

기본 환경 설정

OPENAI_API_KEY = ""
client = OpenAI(api_key = OPENAI_API_KEY)

app = FastAPI()

'''
streamlit으로부터 여러 대화메시지를 받고 그 메시지에 대한 응답들을 streamlit으로 던져줌.
메시지들은 openai의 format과 동일하게하고 streamlit은 누적된 message의 history를
messages로 묶어서 나에게 보내준다.

<<Requset 형식>>
response = client.chat.completions.create(  
        model = "gpt-3.5-turbo",
        messages= messages
    )

<<gpt response 형식>>
response.choices[0].message.content
'''

채팅하는 chat 함수

def chat(messages):
    response = client.chat.completions.create(
        model = "gpt-3.5-turbo",
        messages=messages
    )
    
    assistant_turn = response.choices[0].message
    return assistant_turn

chat 함수는 assistant_turn을 반환. 쉽게 말하면 assistant의 응답을 저장. 이건 openai DTO로 되어있어서 우리가 사용하려면 response.choices[0].message.content로 string만 사용하던가 pydantic의 BaseModel의 mode_dump() 메서드로 dictionary 자료형으로 변환해야한다. 우리의 경우 dictionary로 변환해야 채팅을 이어갈때 편하니까(그냥 append만 하면 됨) 딕셔너리로 변환하자.

자료형 선언

class Turn(BaseModel):
    role: str
    content: str

class Messages(BaseModel):
    messages: List[Turn] # [{"role":"user", "content":"~~~"},{"role":"assistant", "content": "~~~"}]

자료형을 위에 처럼 선언해놓으면 입력값, 반환값을 딕셔너리에서 openai DTO랑 맞출수있어서 편하다.

post

@app.post("/chat", response_model=Turn)#response_model로 response 형태도 정할 수 있다.
def post_chat(messages: Messages):
    messages = messages.model_dump()#dict() = model_dump(mode=dict)
    assistant_turn=chat(messages=messages['messages'])
    return assistant_turn

response_model = Turn으로 반환값도 Turn 자료형이다.

사용자에게 입력받은 메시지를 dict 형태로 변환해서 chatgpt에 물어보고 그 답변을 반환한다.

반환 형식은 swagger ui에서 확인 가능. code 200번은 성공시, code 422는 실패시다.

아래는 각각 우리 request body와 반환값 형식이다.

{
  "messages": [
    {
      "role": "string",
      "content": "string"
    }
  ]
}
{
  "role": "string",
  "content": "string"
}

'인공지능 > LLM' 카테고리의 다른 글

Knowledge Distillation - LLM  (0) 2024.03.17
RAG란?  (0) 2024.03.17
챗봇 구현 실습 (3) - streamlit  (0) 2024.03.17
챗봇 구현 실습 (2) - FastAPI  (1) 2024.03.17
챗봇 구현 실습 (1) - OpenAI API  (0) 2024.03.17
728x90

streamlit은 python만으로 쉽게 웹사이트를 만드는 라이브러리중 하나이다. 이를 통해 python code 몇 줄로 사이트를 만들 수 있다. 많은 api를 제공한다. ui component도 다양하다.

실습

실행 방법

streamlit run [파일명.py]

streamlit은 “”” “”” 안에 있는 문장을 markdown 으로 인식해서 마크다운 문서로 만들어준다.

제목과 내용

st.title("this is title")
st.write("this is text")

input box

st.text_input("text input")

check box

selected = st.checkbox("개인정보 사용에 동의하시겠습니까?")
if selected:
   st.success("동의했습니다.")

select box

market = st.selectbox('시장',('코스닥','코스피','나스닥'))
st.write(f"selected market: {market}")

multiselect

options = st.multiselect('종목',
               ['네이버','카카오','삼성전자','현대자동차'])

st.write(options)
options = st.multiselect('종목',
               ['네이버','카카오','삼성전자','현대자동차'])

st.write(options)
#join 사용시
st.write(', '.join(options))

join 함수는 사용한 string을 이용해서 전달받은 리스트 안의 모든 element를 연결한다.

metric

st.metric(label="네이버",value = "200000 원",delta="1000 원")

지표를 나타내는데 사용할 수 있다.

실습

실행 방법

streamlit run [파일명.py]

streamlit은 “”” “”” 안에 있는 문장을 markdown 으로 인식해서 마크다운 문서로 만들어준다.

제목과 내용

st.title("this is title")
st.write("this is text")

input box

st.text_input("text input")

check box

selected = st.checkbox("개인정보 사용에 동의하시겠습니까?")
if selected:
   st.success("동의했습니다.")

select box

market = st.selectbox('시장',('코스닥','코스피','나스닥'))
st.write(f"selected market: {market}")

multiselect

options = st.multiselect('종목',
               ['네이버','카카오','삼성전자','현대자동차'])

st.write(options)
options = st.multiselect('종목',
               ['네이버','카카오','삼성전자','현대자동차'])

st.write(options)
#join 사용시
st.write(', '.join(options))

join 함수는 사용한 string을 이용해서 전달받은 리스트 안의 모든 element를 연결한다.

metric

st.metric(label="네이버",value = "200000 원",delta="1000 원")

지표를 나타내는데 사용할 수 있다.

'인공지능 > LLM' 카테고리의 다른 글

RAG란?  (0) 2024.03.17
챗봇 구현 실습 (4) - 챗봇 구현  (0) 2024.03.17
챗봇 구현 실습 (2) - FastAPI  (1) 2024.03.17
챗봇 구현 실습 (1) - OpenAI API  (0) 2024.03.17
OpenAI API 설명 (GPT)  (0) 2024.03.17
728x90

fastapi는 python 3.6+ 의 api를 빌드하기위한 웹 프레임워크

= 백엔드에서 restful api를 간결하게 구현할 수 있는 프레임워크

api란?

우리가 해당 서비스의 구동 원리를 몰라도 해당 서비스를 사용하게 해주는 인터페이스.

실습

환경 설정

pip install fastapi
#for production, Uvicorn or Hypercorn과 같은 ASGI 서버기 필요
pip install "uvicorn[standard]"

예제 코드

from typing import Union

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}

원래는 def 해서 함수를 만들면 해당 함수의 기능만 하지만 @app.get(”/”)을 위에 붙임으로써(어노테이션) FastAPI()에 정의된 다른 함수 및 기능까지 사용하게됨.

@app.get("/")
def read_root():
    return {"Hello": "World"}

이 코드의 의미는 해당 홈페이지의 루트(/)로 접근하면 {"Hello": "World"} 를 return 하라는 의미이다.

웹에는 CRUD라는 개념이 있다. 각각 Create, Read, Update, Delete이다.

app.get : Read
app.post : Create
app.put : Update
app.delete : Delete

프로그램 실행

uvicorn main:app --reload

여기서 main은 .py 파일명이고 app은 FastAPI() 클래스의 객체를 의미한다. —reload 옵션을 주면 코드의 변경을 저장할때 자동으로 서버에 반영해준다. 코드짜고 ctrl + s 하면 자동으로 연동이 된다.

path parameter

#Path parameter
@app.get("/items/{item_id}/{key}")
def read_item(item_id: int):#: int부분은 타입핑으로 fast api에 자료형에 대한 힌트를 준다. typing은 python에서 지원하는 기능.
    item = items[item_id]
    return item

#query parameter
@app.get("/items/{item_id}/{key}")
def read_item_and_key(item_id: int,key:str):#: int부분은 타입핑으로 fast api에 자료형에 대한 힌트를 준다. typing은 python에서 지원하는 기능.
    item = items[item_id][key]
    return item

query parameter

#query parameter
@app.get("/item-by-name")
def read_item_by_name(name:str):
    for item_id, item in items.items():
        if item['name'] == name: 
            return item
    return {"error":"data not found"}

127.0.0.1:8000/item-by-name에서 검색을 사용할 수 있다. 검색을 할때 연산자는 ?이고 ? 뒤에 검색할 변수명= 변수에 저장된 값 을 하면 된다.

127.0.0.1:8000/item-by-name?name=bread

post

여기서는 from pydantic import BaseModel 을 추가해야한다. pydantic은 타입을 지정하는걸 도와주는 라이브러리. 데이터를 전달할때 규약을 정해준다고 함.

class Item(BaseModel):
    name: str
    price: int

위의 코드를 추가해서 외부에서 post 메서드로 서버에 요청이 온다면 Item의 형식에 맞는 입력이 있을때 입력대로 parsing을 해서 정보를 가져온다.

@app.post("/items/{item_id}") #이 경로로 create item을 하길 원한다.
def create_item(item_id: int, item: Item):
    if item_id in items:
        return {"error":"there is already existing key."}
    items[item_id] = item.dict() 
    return {"success": "ok"}

put

create에 해당하는 작업

class ItemForUpdate(BaseModel):
    name: Optional[str]
    price: Optional[int]

Item을 update 할때 name or price가 없는 경우 오류가 발생. 이를 처리하기 위해 optional을 줘서 하나가 없어도 오류 안나게 한다.

@app.put("/items/{item_id}")
def update_item(item_id:int, item:ItemForUpdate):
    if item_id not in items:
        return {"error":f"there is no item id {item_id}"}
    
    if item.name:
        items[item_id]['name'] = item.name
    
    if item.price:
        items[item_id]['price'] = item.price 
    
    return {"success": "ok"}

delete

@app.delete("/items/{item_id}")
def delete_item(item_id: int):
    items.pop(item_id)

    return {"success": "ok"}

'인공지능 > LLM' 카테고리의 다른 글

챗봇 구현 실습 (4) - 챗봇 구현  (0) 2024.03.17
챗봇 구현 실습 (3) - streamlit  (0) 2024.03.17
챗봇 구현 실습 (1) - OpenAI API  (0) 2024.03.17
OpenAI API 설명 (GPT)  (0) 2024.03.17
LLAMA2 (3) 답변 받기  (1) 2024.03.15
728x90

실습

completion model

import os
import openai

#openai.api_key = os.get_env("OPENAI_API_KEY")
openai.api_key = "OPENAI_API_KEY"

query = input("입력하세요>> ")

prompt = """
다음 문장이 긍정이면 positive, 부정이면 negative를 만들어라

text: 이 영화 최악이다
sentiment: negative

text: 배우들이 연기를 너무 잘하네
sentiment: positive

text: """

prompt = prompt + query + "\\nsentiment:"

response = openai.completions.create(model="text-davinci-003",
                                     prompt = prompt, 
                                     temperature=0,
                                     max_tokens=7)

print(response.choices[0].text)

simple chatbot by chat completion model

import openai
from openai import OpenAI

OPENAI_API_KEY = ""
client = OpenAI(api_key = OPENAI_API_KEY)

system_instruction = """
너는 햄버거 가게 AI비서야

아래는 햄버거 종류야. 아래 종류의 버거 말고는 다른 버거는 없어

- 빅맥
- 쿼터파운더
- 치즈버거

위의 메뉴 말고는 없다고 생각하면돼
"""

messages = [{"role": "system", "content" : system_instruction}]

def ask(text):
    user_input = {"role": "user", "content": text}
    messages.append(user_input)

    response = client.chat.completions.create(  
        model = "gpt-3.5-turbo",
        messages= messages
    )

    bot_text = response.choices[0].message.content
    bot_resp = {"role": "assistant", "content": bot_text}
    messages.append(bot_resp)

    return bot_text

while True:
    user_input = input("user input: ")
    bot_resp = ask(user_input)

    print("-"*30)
    print(f"user_input: {user_input}")
    print(f"bot_resp: {bot_resp}")

'인공지능 > LLM' 카테고리의 다른 글

챗봇 구현 실습 (3) - streamlit  (0) 2024.03.17
챗봇 구현 실습 (2) - FastAPI  (1) 2024.03.17
OpenAI API 설명 (GPT)  (0) 2024.03.17
LLAMA2 (3) 답변 받기  (1) 2024.03.15
LLAMA2 (2) 환경설정  (1) 2024.03.15

+ Recent posts