2024. 12. 13. 10:57ㆍLLM(Large Language Model)의 기초
1.FAST API란?
* FastAPI는 Python 기반의 웹 프레임워크로, 주로 API를 빠르게 개발하기 위해 설계되었습니다.
* FastAPI는 자동으로 생성되는 OpenAPI 문서(Swagger UI)를 통해 API의 사용성과 테스트를 쉽게 할 수 있으며, 데이터 유효성 검사와 타입 힌트를 활용한 코드 자동완성 및 오류 방지를 지원합니다.
* 특히, 비동기 처리를 활용하여 속도가 중요한 대규모 애플리케이션 개발에 적합하며, RESTful API와 GraphQL 같은 현대적 웹 API 개발에 유용합니다.
*타입 힌팅(Type Hints)
* 타입 힌팅(Type Hints)은 프로그래밍 언어에서 변수, 함수 매개변수, 함수 반환값 등에 대한 데이터 타입 정보를 코드에 명시적으로 제공하는 기술입니다.
* Python 3.5 이상에서 도입된 기능으로, 코드의 가독성을 높이고 프로그램의 안정성을 강화하는 데 도움이 됩니다.
2. Fast API vs Flask vs Django의 장단점
FastApi
장점
* FastAPI는 최신 Python 기반 프레임워크로 빠른 성능과 사용하기 쉬운 API로 유명합니다.
* 비동기 프로그래밍을 지원하므로 실시간 애플리케이션 구축에 적합합니다. 또한 자동 API 문서화 및 유효성 검사를 제공하여 개발자의 시간과 노력을 절약합니다.
단점
* FastAPI는 비교적 새로운 프레임워크이며 기존 프레임워크에 비해 커뮤니티 지원 및 리소스가 많지 않을 수 있습니다. 또한 비동기 프로그래밍을 처음 접하는 개발자를 위한 학습 곡선도 있습니다.
활용도
* FastAPI는 특히 데이터 집약적인 애플리케이션을 위한 실시간 및 고성능 API 구축에 적합합니다.
Django
장점
* Django는 웹 애플리케이션 개발에 널리 사용되는 성숙한 Python 기반 프레임워크입니다.
* 인증, 관리자 패널 및 ORM과 같은 많은 기본 기능을 제공합니다. 또한 지원 및 리소스를 제공하는 크고 활동적인 커뮤니티가 있습니다.
단점
* Django는 복잡할 수 있으며 설정하려면 상당한 구성이 필요합니다.
* 소규모 프로젝트나 경량 API 구축에는 적합하지 않을 수도 있습니다.
활용
* Django는 웹 애플리케이션, 특히 콘텐츠 기반 웹사이트, 전자상거래 플랫폼 및 소셜 미디어 플랫폼을 구축하는 데 널리 사용됩니다.
Flask
장점
* Flask는 배우고 사용하기 쉬운 경량 Python 기반 프레임워크입니다.
* 유연성을 제공하고 개발자가 모듈식 및 확장 가능한 방식으로 웹 애플리케이션을 구축할 수 있도록 합니다. 또한 사용자 정의가 가능하고 소규모 프로젝트를 구축하는 데 적합합니다.
단점
*Flask는 다른 프레임워크에 비해 기본 제공 기능이 적기 때문에 개발자가 구현하는 데 더 많은 노력과 시간이 필요할 수 있습니다.
* 또한 대규모 웹 애플리케이션을 구축하는 데 적합하지 않을 수도 있습니다.
활용
Flask는 개인 웹 사이트, 간단한 API 및 내부 대시보드와 같은 소규모 웹 애플리케이션 및 프로토타입을 구축하는 데 적합합니다.
요약
* FastAPI는 실시간 및 고성능 API를 구축하는 데 적합한 현대적이고 빠른 프레임워크이고, Django는 복잡한 웹 애플리케이션을 구축하는 데 적합한 성숙한 프레임워크이며, Flask는 소규모 웹 애플리케이션 및 프로토타입을 구축하는 데 적합한 가볍고 유연한 프레임워크입니다.
* 그들 사이의 선택은 개발 팀의 기술과 경험뿐만 아니라 프로젝트의 특정 요구 사항과 요구 사항에 따라 다릅니다.
3. 비동기 프로그래밍
* 비동기 프로그래밍은 코드가 병렬적으로 실행되는 것처럼 보이게 하는 프로그래밍 방식입니다.
* 이는 특히 I/O 작업(네트워크 요청, 파일 읽기/쓰기 등)에서 시간을 절약하고 프로그램의 성능을 최적화하는 데 유용합니다.
3-1. 동기(Synchronous)
* 작업이 순차적으로 실행됩니다.
* 하나의 작업이 끝날 때까지 다음 작업이 대기합니다.
예시 1)
예시)
# def 키워드로 선언하는 모든 함수는 파이썬에서 기본적으로 동기 방식으로 동작
def do_sync():
print("do_sync")
do_sync()
-->
do_sync
3-2. 비동기(Asynchronous)
* 작업이 독립적으로 실행되며, 대기 시간이 발생하면 다른 작업을 처리할 수 있습니다
예시)
import asyncio
async def do_async():
print("do_async")
# 비동기 함수는 일반적으로 async 로 선언된 다른 비동기 함수 내에서 await 키워드를 붙여서 호출해야 함
# await 는 비동기 함수나 코루틴의 실행을 일시 중단하고 다른 작업을 처리할 수 있도록 함
async def main_async():
await do_async()
# async 로 선언되지 않은 일반 동기 함수 내에서 비동기 함수를 호출하려면 asyncio.run 을 이용
asyncio.run(main_async())
#-->
#do_async
※ 코루틴(Coroutine)
* 파이썬에서 비동기 프로그래밍을 구현하기 위해 사용하는 특별한 형태의 함수입니다.
* 일반 함수와는 달리, 코루틴은 실행 중에 멈췄다가 다시 실행을 재개할 수 있습니다.
* 이를 통해 작업을 효율적으로 분할하고 비동기 처리를 가능하게 합니다.
예시 3)
import asyncio
async def task(name, duration):
print(f"{name} 시작")
await asyncio.sleep(duration)
print(f"{name} 완료")
async def main():
await asyncio.gather(
task("작업 1", 2),
task("작업 2", 3),
task("작업 3", 1)
)
asyncio.run(main())
#-->
#작업 1 시작
#작업 2 시작
#작업 3 시작
#작업 3 완료
#작업 1 완료
#작업 2 완료
4. 비동기 프로그래밍을 사용하는 이유
4-1.
* 응답성(Responsiveness): 비동기 작업은 여러 작업을 동시에 처리하고, 작업이 완료되기를 기다리는 동안 다른 작업을 처리할 수 있습니다.
- 이로써 프로그램의 응답성이 향상되고, 장기 실행 작업이 다른 작업을 차단하지 않도록 할 수 있습니다.
- 예를 들어, 네트워크 요청이나 데이터베이스 조회 등의 I/O 작업을 비동기로 처리하면, 다른 작업을 수행하면서 응답을 기다릴 필요가 없어집니다.
4-2.
* 확장성(Scalability): 비동기 프로그래밍은 많은 수의 동시 요청 또는 작업을 처리할 때 유용합니다.
- 여러 작업을 동시에 실행하고 완료될 때까지 기다리지 않아도 되므로, 처리량과 처리 속도를 향상할 수 있습니다.
- 이는 웹 서버, 네트워크 서비스, 데이터 파이프라인 등과 같은 시스템의 확장성을 향상하는 데 도움이 됩니다.
4-3.
* 자원 효율성(Resource Efficiency): 비동기 작업은 작업의 대기 시간 동안 자원을 효율적으로 활용할 수 있습니다.
- 대기 시간 동안 CPU나 메모리 등의 자원을 다른 작업에 할당하여 더 많은 작업을 처리할 수 있습니다.
- 이는 시스템의 자원 이용률을 높이고, 전체적인 성능을 향상할 수 있습니다.
4-4.
* 병렬성(Concurrency): 비동기 프로그래밍은 병렬적인 작업을 효율적으로 처리할 수 있는 방법을 제공합니다.
- 여러 작업이 동시에 실행될 수 있으며, 이는 멀티코어 프로세서를 활용하여 작업을 분산 처리할 수 있음을 의미합니다.
- 이를 통해 병렬성을 높여 전체적인 처리 시간을 단축시킬 수 있습니다.
5. FASTAPI
* FastAPI 애플리케이션을 실행하기 위해 uvicorn이라는 ASGI 서버가 필요합니다.
* Uvicorn은 Python으로 작성된 가볍고 빠른 웹 서버로, 비동기 웹 애플리케이션과 API를 실행하는 데 사용됩니다.
* 특히 FastAPI와 잘 어울리며, WebSocket과 HTTP/2 같은 최신 웹 기술을 지원합니다.
* 개발할 때는 자동 리로드 기능으로 편리하게 작업할 수 있고, 운영 환경에서는 다중 프로세스로 높은 성능을 제공합니다.
6. uvicorn [standard]
1. 이 패키지는 uvicorn에 기본적으로 포함된 기능 외에도 추가적인 표준 미들웨어를 포함합니다.
2. 표준 미들웨어는 보안, 로깅 및 기타 서버 관련 기능을 추가하는 데 도움이 됩니다.
3. 예를 들어, Gzip 압축, CORS(Cross-Origin Resource Sharing) 지원 등이 기본적으로 포함되어 있습니다.
uvicorn 설치
pip install "uvicorn[standard]"
FAST API 사용법
1. 우선 venv를 생성한다.
python -m venv venv 생성
venv/Scripts 가서 activate.bat을 실행
2. FAST API 설치
pip install fastapi
uvicorn
1. 기본적으로 필요한 최소한의 기능만을 제공하는 패키지입니다.
2. uvicorn [standard]에 비해 미들웨어가 적고, 기본적인 서버 기능만을 제공합니다.
※ ASGI 서버
* ASGI 서버는 Python에서 비동기 웹 애플리케이션을 실행할 수 있게 해주는 서버입니다.
* 기존의 WSGI 서버는 동작이 느리고 실시간 기능(WebSocket, HTTP/2 등)을 지원하지 않았지만, ASGI 서버는 비동기로 동작해 더 빠르고 실시간 데이터 처리도 가능합니다.
* FastAPI 같은 최신 웹 프레임워크가 ASGI 서버와 잘 어울리며, 대표적인 서버로 Uvicorn과 Daphne가 있습니다.
* 이를 통해 많은 요청을 동시에 처리하고, 실시간 기능이 필요한 앱을 쉽게 만들 수 있습니다.
http://127.0.0.1:8000/docs (포스트맨 대신 실해해 줘서 편하다.)
uvicorn 설치
pip install "uvicorn[standard]"
http://127.0.0.1:8000/docs에 들어가면 PostMan 대신에 실행해 준다.
main.py 생성 후 작성해 주면 이렇게 돌아간다.
from fastapi import FastAPI
users = {
0: {"userid": "apple", "name": "김사과"},
1: {"userid": "banana", "name": "반하나"},
2: {"userid": "orange", "name": "오렌지"}
}
app = FastAPI()
# http://127.0.0.1:8000/users/0
@app.get("/users/{id}")
def find_user(id: int):
user = users[id]
return user
4. FAST API 실행
- FastAPI 애플리케이션을 실행하기 위해 uvicorn이라는 ASGI 서버가 필요합니다. Uvicorn은 Python으로 작성된 가볍고 빠른 웹 서버로, 비동기 웹 애플리케이션과 API를 실행하는 데 사용됩니다.
특히 FastAPI와 잘 어울리며, WebSocket과 HTTP/2 같은 최신 웹 기술을 지원합니다. 개발할 때는 자동 리로드 기능으로 편리하게 작업할 수 있고, 운영 환경에서는 다중 프로세스로 높은 성능을 제공합니다
그러면 제대로 받아온 걸 확인해 볼 수 있다.
2. Gradiod 와 FAST API 연결하는법
1. app.py 파일
#app.py 파일
import gradio as gr
import requests
# 광고 문구 생성 함수
def generate_ad(product_name, details, options):
url = "http://127.0.0.1:8000/create_ad"
try:
response = requests.post(
url,
json={
"product_name":product_name,
"details":details,
"tone_and_manner":", ".join(options)
}
)
if response.status_code == 200:
data = response.json()
ad = data["ad"]
return ad
else:
return "광고 문구 생성 실패!"
except:
return "서버 연결 실패"
# Gradio 화면 구성
def main():
with gr.Blocks() as demo:
gr.Markdown("광고 문구를 생성해주는 서비스 앱")
with gr.Row():
product_name = gr.Textbox(label="제품 이름", placeholder="제품 이름을 입력하세요")
details = gr.Textbox(label="주요 내용", placeholder="제품의 주요 내용을 입력하세요")
options = gr.CheckboxGroup(
label="광고 문구의 느낌",
choices=["기본", "재밌게", "차분하게", "과장스럽게", "참신하게", "고급스럽게", "센스있게", "가볍게"], value=["기본"]
)
generate_button = gr.Button("문구 생성하기")
ad_output = gr.Textbox(label="생성된 광고 문구", interactive=False)
generate_button.click(
generate_ad,
inputs=[product_name, details, options],
outputs=[ad_output]
)
return demo
# 실행
if __name__ == "__main__":
app = main()
app.launch()
-->
설명글 추가(참고)
import gradio as gr # Gradio 라이브러리를 가져와 웹 기반 인터페이스를 생성하는 데 사용
import requests # HTTP 요청을 보내기 위한 requests 라이브러리
# 광고 문구 생성 함수
def generate_ad(product_name, details, options):
"""
광고 문구를 생성하기 위해 서버에 요청을 보내고 결과를 반환하는 함수입니다.
Args:
product_name (str): 제품의 이름
details (str): 제품의 주요 내용
options (list): 광고 문구의 느낌을 담은 옵션들
Returns:
str: 생성된 광고 문구 또는 오류 메시지
"""
url = "http://127.0.0.1:8000/create_ad" # 광고 문구 생성 요청을 보낼 서버의 URL
try:
# POST 요청을 보내면서 제품명, 상세 내용, 광고 톤을 JSON 형식으로 전달
response = requests.post(
url,
json={
"product_name": product_name,
"details": details,
"tone_and_manner": ", ".join(options) # 선택된 옵션들을 문자열로 병합
}
)
# 서버 응답이 성공적일 경우
if response.status_code == 200:
data = response.json() # JSON 형식으로 응답 데이터를 파싱
ad = data["ad"] # 응답에서 광고 문구를 추출
return ad
else:
return "광고 문구 생성 실패!" # 서버가 성공적으로 응답하지 못한 경우
except:
return "서버 연결 실패" # 서버에 연결할 수 없는 경우
# Gradio 화면 구성 함수
def main():
"""
Gradio를 사용해 사용자 인터페이스를 생성하는 함수입니다.
"""
with gr.Blocks() as demo: # Gradio Blocks 컨테이너를 생성
gr.Markdown("광고 문구를 생성해주는 서비스 앱") # 앱의 제목 및 설명
# 사용자 입력 필드를 수평으로 배치
with gr.Row():
product_name = gr.Textbox(label="제품 이름", placeholder="제품 이름을 입력하세요") # 제품 이름 입력창
details = gr.Textbox(label="주요 내용", placeholder="제품의 주요 내용을 입력하세요") # 제품 주요 내용 입력창
# 광고 문구의 느낌을 선택할 수 있는 체크박스 그룹
options = gr.CheckboxGroup(
label="광고 문구의 느낌",
choices=["기본", "재밌게", "차분하게", "과장스럽게", "참신하게", "고급스럽게", "센스있게", "가볍게"],
value=["기본"] # 기본 선택값 설정
)
# 문구 생성 버튼
generate_button = gr.Button("문구 생성하기") # 버튼 생성
# 생성된 광고 문구를 표시할 출력창 (편집 불가능)
ad_output = gr.Textbox(label="생성된 광고 문구", interactive=False)
# 버튼 클릭 시 `generate_ad` 함수 호출
generate_button.click(
generate_ad, # 호출할 함수
inputs=[product_name, details, options], # 입력값으로 사용할 요소들
outputs=[ad_output] # 출력값을 표시할 요소
)
return demo # 생성된 Gradio 인터페이스 반환
# 실행
if __name__ == "__main__":
app = main() # Gradio 앱 생성
app.launch() # 로컬 서버에서 Gradio 앱 실행
2. main.py
import openai
from fastapi import FastAPI
from pydantic import BaseModel
from pymongo import MongoClient
openai.api_key="api_key키 입력"
url = "몽고DB 주소입력"
mongodb = MongoClient(url)
database = mongodb['kdt']
collection = database['gptad']
class AdGenerator:
def __init__(self, engine='gpt-3.5-turbo'):
self.engine = engine
def using_chatgpt(self, prompt):
system_instruction = "assistant는 마케팅 문구 작성 도우미로 동작한다. user의 내용을 참고하여 마케팅 문구를 작성해라."
messages = [{"role":"system", "content":system_instruction},
{"role":"user", "content": prompt}]
response = openai.chat.completions.create(model=self.engine, messages=messages)
result = response.choices[0].message.content.strip()
return result
def generate_prompt(self, product_name, details, tone_and_manner):
prompt = f'제품 이름: {product_name}\n주요 내용: {details}\n광고 문구의 스타일: {tone_and_manner}\n위 내용을 참고하여 마케팅 문구를 만들어라'
result = self.using_chatgpt(prompt=prompt)
return result
class Product(BaseModel):
product_name: str
details: str
tone_and_manner: str
app = FastAPI()
@app.post("/create_ad")
async def create_ad(product: Product):
ad_generator = AdGenerator()
ad = ad_generator.generate_prompt(
product_name=product.product_name,
details=product.details,
tone_and_manner=product.tone_and_manner
)
data_insert = {
"product_name": product.product_name,
"details": product.details,
"tone_and_manner": product.tone_and_manner,
"ad": ad
}
result = collection.insert_one(data_insert)
print(result.inserted_id)
return {"ad": ad}
-->
설명글 추가(참고)
import openai # OpenAI API를 사용하기 위한 라이브러리
from fastapi import FastAPI # FastAPI 웹 프레임워크를 가져옴
from pydantic import BaseModel # 데이터 검증 및 모델링을 위한 Pydantic 라이브러리
from pymongo import MongoClient # MongoDB와 상호작용하기 위한 라이브러리
# OpenAI API 키 설정 (사용자의 API 키로 교체 필요)
openai.api_key = "api_key키 입력"
# MongoDB 클라이언트 연결 설정 (MongoDB 주소 입력 필요)
url = "몽고DB 주소입력"
mongodb = MongoClient(url) # MongoDB 클라이언트 생성
database = mongodb['kdt'] # 'kdt'라는 이름의 데이터베이스 선택
collection = database['gptad'] # 'gptad'라는 이름의 컬렉션 선택
# 광고 생성 클래스 정의
class AdGenerator:
def __init__(self, engine='gpt-3.5-turbo'):
"""
AdGenerator 클래스의 생성자.
Args:
engine (str): 사용할 OpenAI 모델의 이름 (기본값은 'gpt-3.5-turbo')
"""
self.engine = engine
def using_chatgpt(self, prompt):
"""
ChatGPT API를 사용해 마케팅 문구를 생성하는 메서드.
Args:
prompt (str): 사용자로부터 전달받은 프롬프트 문자열
Returns:
str: 생성된 마케팅 문구
"""
# 시스템 메시지: AI가 마케팅 문구 도우미로 동작하도록 지시
system_instruction = "assistant는 마케팅 문구 작성 도우미로 동작한다. user의 내용을 참고하여 마케팅 문구를 작성해라."
# 메시지 리스트 생성 (시스템 메시지 + 사용자 메시지)
messages = [
{"role": "system", "content": system_instruction},
{"role": "user", "content": prompt}
]
# OpenAI API를 호출하여 응답 받기
response = openai.chat.completions.create(model=self.engine, messages=messages)
# 응답에서 생성된 문구를 추출하고 앞뒤 공백을 제거
result = response.choices[0].message.content.strip()
return result
def generate_prompt(self, product_name, details, tone_and_manner):
"""
사용자 입력을 기반으로 프롬프트를 생성하고 마케팅 문구를 생성하는 메서드.
Args:
product_name (str): 제품 이름
details (str): 제품의 주요 내용
tone_and_manner (str): 광고 문구의 스타일 (톤과 느낌)
Returns:
str: 생성된 마케팅 문구
"""
# 프롬프트 텍스트 생성
prompt = (
f'제품 이름: {product_name}\n'
f'주요 내용: {details}\n'
f'광고 문구의 스타일: {tone_and_manner}\n'
f'위 내용을 참고하여 마케팅 문구를 만들어라'
)
# ChatGPT를 사용해 프롬프트로부터 광고 문구 생성
result = self.using_chatgpt(prompt=prompt)
return result
# FastAPI의 데이터 모델 정의 (입력값의 스키마를 지정)
class Product(BaseModel):
product_name: str # 제품 이름
details: str # 제품의 주요 내용
tone_and_manner: str # 광고 문구의 스타일 (톤과 느낌)
# FastAPI 앱 생성
app = FastAPI()
# 광고 문구 생성 API 엔드포인트
@app.post("/create_ad")
async def create_ad(product: Product):
"""
광고 문구를 생성하는 POST 요청 핸들러.
Args:
product (Product): 제품 이름, 주요 내용, 광고 스타일이 담긴 요청 데이터
Returns:
dict: 생성된 광고 문구를 담은 딕셔너리
"""
# AdGenerator 클래스의 인스턴스 생성
ad_generator = AdGenerator()
# 광고 문구 생성
ad = ad_generator.generate_prompt(
product_name=product.product_name,
details=product.details,
tone_and_manner=product.tone_and_manner
)
# MongoDB에 데이터 삽입
data_insert = {
"product_name": product.product_name,
"details": product.details,
"tone_and_manner": product.tone_and_manner,
"ad": ad
}
result = collection.insert_one(data_insert) # 데이터베이스에 문서 삽입
print(result.inserted_id) # 삽입된 문서의 ID 출력
# 생성된 광고 문구를 반환
return {"ad": ad}
'LLM(Large Language Model)의 기초' 카테고리의 다른 글
1. 판다스(Pandas) (2) | 2024.12.17 |
---|---|
넘파이(Numpy) (0) | 2024.12.16 |
Gradio (3) | 2024.12.11 |
프롬프트 엔지니어링 (8) | 2024.12.11 |
몽고 DB 와 파이썬 (6) | 2024.12.10 |