์ธ๊ณต์ง๋ฅ
ํ์ด์ฌ์์ ๋น๋๊ธฐ LLM API ํธ์ถ: ํฌ๊ด์ ์ธ ๊ฐ์ด๋

๊ฐ๋ฐ์์ด์ dta ๊ณผํ์๋ก์ ์ฐ๋ฆฌ๋ ์ข ์ข API๋ฅผ ํตํด ์ด๋ฌํ ๊ฐ๋ ฅํ ๋ชจ๋ธ๊ณผ ์ํธ ์์ฉํด์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ณต์ก์ฑ๊ณผ ๊ท๋ชจ๊ฐ ์ปค์ง์ ๋ฐ๋ผ ํจ์จ์ ์ด๊ณ ์ฑ๋ฅ์ด ๋ฐ์ด๋ API ์ํธ ์์ฉ์ ๋ํ ํ์์ฑ์ด ์ค์ํด์ง๋๋ค. ์ฌ๊ธฐ์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ด ๋น์ ๋ฐํ๋ฉฐ, LLM API๋ก ์์ ํ ๋ ์ฒ๋ฆฌ๋์ ๊ทน๋ํํ๊ณ ์ง์ฐ ์๊ฐ์ ์ต์ํํ ์ ์์ต๋๋ค.
์ด ์ข ํฉ ๊ฐ์ด๋์์๋ Python์์ ๋น๋๊ธฐ LLM API ํธ์ถ์ ์ธ๊ณ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๊ธฐ๋ณธ๋ถํฐ ๋ณต์กํ ์ํฌํ๋ก์ฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ณ ๊ธ ๊ธฐ์ ๊น์ง ๋ชจ๋ ๊ฒ์ ๋ค๋ฃน๋๋ค. ์ด ๊ธ์ ๋ง์น๋ฉด ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ํ์ฉํ์ฌ LLM ๊ธฐ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐํํ๋ ๋ฐฉ๋ฒ์ ํ์คํ ์ดํดํ๊ฒ ๋ ๊ฒ์ ๋๋ค.
๋น๋๊ธฐ LLM API ํธ์ถ์ ์ธ๋ถ ์ฌํญ์ ์ดํด๋ณด๊ธฐ ์ ์ ๋จผ์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ ๊ฐ๋ ์ ๋ํ ํผํผํ ๊ธฐ์ด๋ฅผ ๋ค์ ธ๋ณด๊ฒ ์ต๋๋ค.
๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ์คํ์ ์ฃผ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ง ์๊ณ ์ฌ๋ฌ ์์ ์ ๋์์ ์คํํ ์ ์๊ฒ ํด์ค๋๋ค. Python์์ ์ด๋ ์ฃผ๋ก ๋ค์์ ํตํด ๋ฌ์ฑ๋ฉ๋๋ค. ๋น๋๊ธฐ ์ฝ๋ฃจํด, ์ด๋ฒคํธ ๋ฃจํ, ํจ์ฒ๋ฅผ ์ฌ์ฉํ์ฌ ๋์์ฑ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํ ํ๋ ์์ํฌ๋ฅผ ์ ๊ณตํ๋ ๋ชจ๋์ ๋๋ค.
์ฃผ์ ๊ฐ๋ :
- ์ฝ๋ฃจํด: ์ ์๋ ํจ์ ๋น๋๊ธฐ ์ ์ ์ผ์ ์ ์ง ๋ฐ ์ฌ๊ฐ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
- ์ด๋ฒคํธ ๋ฃจํ: ๋น๋๊ธฐ ์์ ์ ๊ด๋ฆฌํ๊ณ ์คํํ๋ ์ค์ ์คํ ๋ฉ์ปค๋์ฆ์ ๋๋ค.
- ๊ธฐ๋๋๋ ๊ฒ๋ค: await ํค์๋์ ํจ๊ป ์ฌ์ฉํ ์ ์๋ ๊ฐ์ฒด(์ฝ๋ฃจํด, ํ์คํฌ, ํจ์ฒ).
์ด๋ฌํ ๊ฐ๋ ์ ์ค๋ช ํ๊ธฐ ์ํ ๊ฐ๋จํ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
import asyncio async def greet(name): await asyncio.sleep(1) # Simulate an I/O operation print(f"Hello, {name}!") async def main(): await asyncio.gather( greet("Alice"), greet("Bob"), greet("Charlie") ) asyncio.run(main())
์ด ์์์ ์ฐ๋ฆฌ๋ ๋น๋๊ธฐ ํจ์๋ฅผ ์ ์ํฉ๋๋ค. greet
I/O ์์
์ ์๋ฎฌ๋ ์ด์
ํ๋ asyncio.sleep()
. ๊ทธ๋งํผ main
๊ธฐ๋ฅ ์ฌ์ฉ asyncio.gather()
์ฌ๋ฌ ์ธ์ฌ๋ง์ ๋์์ ์คํํฉ๋๋ค. sleep ์ง์ฐ์๋ ๋ถ๊ตฌํ๊ณ ์ธ ์ธ์ฌ๋ง์ด ๋ชจ๋ ์ฝ 1์ด ํ์ ์ธ์๋์ด ๋น๋๊ธฐ ์คํ์ ํ์ ๋ณด์ฌ์ค๋๋ค.
LLM API ํธ์ถ์์ ๋น๋๊ธฐ์ ํ์์ฑ
LLM API๋ก ์์ ํ ๋, ์ฐ๋ฆฌ๋ ์ข ์ข ์ฌ๋ฌ API ํธ์ถ์ ์์๋๋ก ๋๋ ๋ณ๋ ฌ๋ก ํด์ผ ํ๋ ์๋๋ฆฌ์ค์ ์ง๋ฉดํฉ๋๋ค. ๊ธฐ์กด์ ๋๊ธฐ ์ฝ๋๋ ์๋นํ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ผ๋ก ์ด์ด์ง ์ ์์ผ๋ฉฐ, ํนํ LLM ์๋น์ค์ ๋ํ ๋คํธ์ํฌ ์์ฒญ๊ณผ ๊ฐ์ ๊ณ ์ง์ฐ ์์ ์ ์ฒ๋ฆฌํ ๋ ๊ทธ๋ ์ต๋๋ค.
LLM API๋ฅผ ์ฌ์ฉํ์ฌ 100๊ฐ์ ์๋ก ๋ค๋ฅธ ๊ธฐ์ฌ์ ๋ํ ์์ฝ์ ์์ฑํด์ผ ํ๋ ์๋๋ฆฌ์ค๋ฅผ ์๊ฐํด ๋ณด๊ฒ ์ต๋๋ค. ๋๊ธฐ์ ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด ๊ฐ API ํธ์ถ์ ์๋ต์ ๋ฐ์ ๋๊น์ง ์ฐจ๋จ๋์ด ๋ชจ๋ ์์ฒญ์ ์๋ฃํ๋ ๋ฐ ๋ช ๋ถ์ด ๊ฑธ๋ฆด ์ ์์ต๋๋ค. ๋ฐ๋ฉด ๋น๋๊ธฐ์ ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ API ํธ์ถ์ ๋์์ ์์ํ ์ ์์ด ์ ์ฒด ์คํ ์๊ฐ์ ํฌ๊ฒ ์ค์ผ ์ ์์ต๋๋ค.
ํ๊ฒฝ ์ค์
๋น๋๊ธฐ LLM API ํธ์ถ์ ์์ํ๋ ค๋ฉด ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ Python ํ๊ฒฝ์ ์ค์ ํด์ผ ํฉ๋๋ค. ํ์ํ ์ฌํญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ํ์ด์ฌ 3.7 ๋๋ ๊ทธ ์ด์(๋ค์ดํฐ๋ธ asyncio ์ง์์ ๊ฒฝ์ฐ)
- aiohttp: ๋น๋๊ธฐ HTTP ํด๋ผ์ด์ธํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- Openai: ๊ณต์ OpenAI Python ํด๋ผ์ด์ธํธ (OpenAI์ GPT ๋ชจ๋ธ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ)
- ๋ญ์ฒด์ธ: LLM์ ์ฌ์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ ์ํ ํ๋ ์์ํฌ(์ ํ ์ฌํญ์ด์ง๋ง ๋ณต์กํ ์ํฌํ๋ก์ ๊ถ์ฅ๋จ)
pip๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฌํ ์ข ์์ฑ์ ์ค์นํ ์ ์์ต๋๋ค.
pip install aiohttp openai langchain <div class="relative flex flex-col rounded-lg">
asyncio ๋ฐ aiohttp๋ฅผ ์ฌ์ฉํ ๊ธฐ๋ณธ ๋น๋๊ธฐ LLM API ํธ์ถ
aiohttp๋ฅผ ์ฌ์ฉํ์ฌ LLM API์ ๋ํ ๊ฐ๋จํ ๋น๋๊ธฐ ํธ์ถ์ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค. OpenAI์ GPT-3.5 API๋ฅผ ์๋ก ๋ค์ด ์ค๋ช ํ๊ฒ ์ง๋ง, ์ด ๊ฐ๋ ์ ๋ค๋ฅธ LLM API์๋ ์ ์ฉ๋ฉ๋๋ค.
import asyncio import aiohttp from openai import AsyncOpenAI async def generate_text(prompt, client): response = await client.chat.completions.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}] ) return response.choices[0].message.content async def main(): prompts = [ "Explain quantum computing in simple terms.", "Write a haiku about artificial intelligence.", "Describe the process of photosynthesis." ] async with AsyncOpenAI() as client: tasks = [generate_text(prompt, client) for prompt in prompts] results = await asyncio.gather(*tasks) for prompt, result in zip(prompts, results): print(f"Prompt: {prompt}\nResponse: {result}\n") asyncio.run(main())
์ด ์์์ ์ฐ๋ฆฌ๋ ๋น๋๊ธฐ ํจ์๋ฅผ ์ ์ํฉ๋๋ค. generate_text
AsyncOpenAI ํด๋ผ์ด์ธํธ๋ฅผ ์ฌ์ฉํ์ฌ OpenAI API๋ฅผ ํธ์ถํฉ๋๋ค. main
์ด ๊ธฐ๋ฅ์ ๋ค์ํ ํ๋กฌํํธ์ ์ฉ๋์ ๋ํด ์ฌ๋ฌ ์์
์ ์์ฑํฉ๋๋ค. asyncio.gather()
๋์์ ์คํํฉ๋๋ค.
์ด ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด LLM API์ ์ฌ๋ฌ ์์ฒญ์ ๋์์ ๋ณด๋ผ ์ ์์ด ๋ชจ๋ ํ๋กฌํํธ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ํ์ํ ์ด ์๊ฐ์ ํฌ๊ฒ ์ค์ผ ์ ์์ต๋๋ค.
๊ณ ๊ธ ๊ธฐ์ : ๋ฐฐ์น ๋ฐ ๋์์ฑ ์ ์ด
์ด์ ์์ ๋ ๋น๋๊ธฐ LLM API ํธ์ถ์ ๊ธฐ๋ณธ์ ๋ณด์ฌ์ฃผ์ง๋ง, ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ๋ ์ ๊ตํ ์ ๊ทผ ๋ฐฉ์์ด ํ์ํ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๋ ๊ฐ์ง ์ค์ํ ๊ธฐ์ , ์ฆ ์์ฒญ ์ผ๊ด ์ฒ๋ฆฌ์ ๋์์ฑ ์ ์ด๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์์ฒญ ์ผ๊ด ์ฒ๋ฆฌ: ๋ง์ ์์ ํ๋กฌํํธ๋ฅผ ์ฒ๋ฆฌํ ๋, ๊ฐ ํ๋กฌํํธ์ ๋ํด ๊ฐ๋ณ ์์ฒญ์ ๋ณด๋ด๋ ๊ฒ๋ณด๋ค ์ฌ๋ฌ ๊ฐ์ ํ๋กฌํํธ๋ฅผ ๋ฌถ์ด ์ผ๊ด ์ฒ๋ฆฌํ๋ ๊ฒ์ด ๋ ํจ์จ์ ์ธ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฌ๋ฌ API ํธ์ถ๋ก ์ธํ ์ค๋ฒํค๋๋ฅผ ์ค์ด๊ณ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
import asyncio from openai import AsyncOpenAI async def process_batch(batch, client): responses = await asyncio.gather(*[ client.chat.completions.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}] ) for prompt in batch ]) return [response.choices[0].message.content for response in responses] async def main(): prompts = [f"Tell me a fact about number {i}" for i in range(100)] batch_size = 10 async with AsyncOpenAI() as client: results = [] for i in range(0, len(prompts), batch_size): batch = prompts[i:i+batch_size] batch_results = await process_batch(batch, client) results.extend(batch_results) for prompt, result in zip(prompts, results): print(f"Prompt: {prompt}\nResponse: {result}\n") asyncio.run(main())
๋์์ฑ ์ ์ด: ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๋์ ์คํ์ ํ์ฉํ์ง๋ง, API ์๋ฒ์ ๊ณผ๋ถํ๊ฐ ๊ฑธ๋ฆฌ๊ฑฐ๋ ์๋ ์ ํ์ ์ด๊ณผํ์ง ์๋๋ก ๋์์ฑ ์์ค์ ์ ์ดํ๋ โโ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ด๋ฅผ ์ํด asyncio.Semaphore๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
import asyncio from openai import AsyncOpenAI async def generate_text(prompt, client, semaphore): async with semaphore: response = await client.chat.completions.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}] ) return response.choices[0].message.content async def main(): prompts = [f"Tell me a fact about number {i}" for i in range(100)] max_concurrent_requests = 5 semaphore = asyncio.Semaphore(max_concurrent_requests) async with AsyncOpenAI() as client: tasks = [generate_text(prompt, client, semaphore) for prompt in prompts] results = await asyncio.gather(*tasks) for prompt, result in zip(prompts, results): print(f"Prompt: {prompt}\nResponse: {result}\n") asyncio.run(main())
์ด ์์์๋ ์ธ๋งํฌ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋์ ์์ฒญ ์๋ฅผ 5๊ฐ๋ก ์ ํํ์ฌ API ์๋ฒ์ ๊ณผ๋ถํ๊ฐ ๊ฑธ๋ฆฌ์ง ์๋๋ก ํฉ๋๋ค.
๋น๋๊ธฐ LLM ํธ์ถ์์์ ์ค๋ฅ ์ฒ๋ฆฌ ๋ฐ ์ฌ์๋
์ธ๋ถ API๋ฅผ ์ฌ์ฉํ ๋๋ ๊ฐ๋ ฅํ ์ค๋ฅ ์ฒ๋ฆฌ ๋ฐ ์ฌ์๋ ๋ฉ์ปค๋์ฆ์ ๊ตฌํํ๋ ๊ฒ์ด ๋งค์ฐ ์ค์ํฉ๋๋ค. ์ผ๋ฐ์ ์ธ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๊ณ ์ฌ์๋์ ๋ํ ์ง์ ๋ฐฑ์คํ๋ฅผ ๊ตฌํํ๋๋ก ์ฝ๋๋ฅผ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
import asyncio import random from openai import AsyncOpenAI from tenacity import retry, stop_after_attempt, wait_exponential class APIError(Exception): pass @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10)) async def generate_text_with_retry(prompt, client): try: response = await client.chat.completions.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}] ) return response.choices[0].message.content except Exception as e: print(f"Error occurred: {e}") raise APIError("Failed to generate text") async def process_prompt(prompt, client, semaphore): async with semaphore: try: result = await generate_text_with_retry(prompt, client) return prompt, result except APIError: return prompt, "Failed to generate response after multiple attempts." async def main(): prompts = [f"Tell me a fact about number {i}" for i in range(20)] max_concurrent_requests = 5 semaphore = asyncio.Semaphore(max_concurrent_requests) async with AsyncOpenAI() as client: tasks = [process_prompt(prompt, client, semaphore) for prompt in prompts] results = await asyncio.gather(*tasks) for prompt, result in results: print(f"Prompt: {prompt}\nResponse: {result}\n") asyncio.run(main())
์ด ํฅ์๋ ๋ฒ์ ์๋ ๋ค์์ด ํฌํจ๋ฉ๋๋ค.
- ์ฌ์ฉ์ ์ง์
APIError
API ๊ด๋ จ ์ค๋ฅ์ ๋ํ ์์ธ์ ๋๋ค. - A
generate_text_with_retry
์ฅ์๋ ๊ธฐ๋ฅ@retry
tenacity ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ง์ ๋ฐฑ์คํ๋ฅผ ๊ตฌํํฉ๋๋ค. - ์ค๋ฅ ์ฒ๋ฆฌ
process_prompt
์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ณ ๋ณด๊ณ ํ๋ ๊ธฐ๋ฅ.
์ฑ๋ฅ ์ต์ ํ: ์คํธ๋ฆฌ๋ฐ ์๋ต
์ฅ๋ฌธ ์ฝํ ์ธ ์์ฑ์ ๊ฒฝ์ฐ ์คํธ๋ฆฌ๋ฐ ์๋ต์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ธ์ง๋ ์ฑ๋ฅ์ ํฌ๊ฒ ๊ฐ์ ํ ์ ์์ต๋๋ค. ์ ์ฒด ์๋ต์ ๊ธฐ๋ค๋ฆฌ๋ ๋์ , ์ฌ์ฉ ๊ฐ๋ฅํด์ง๋ฉด ํ ์คํธ ์ฒญํฌ๋ฅผ ์ฒ๋ฆฌํ๊ณ ํ์ํ ์ ์์ต๋๋ค.
import asyncio from openai import AsyncOpenAI async def stream_text(prompt, client): stream = await client.chat.completions.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}], stream=True ) full_response = "" async for chunk in stream: if chunk.choices[0].delta.content is not None: content = chunk.choices[0].delta.content full_response += content print(content, end='', flush=True) print("\n") return full_response async def main(): prompt = "Write a short story about a time-traveling scientist." async with AsyncOpenAI() as client: result = await stream_text(prompt, client) print(f"Full response:\n{result}") asyncio.run(main())
์ด ์์ ๋ API์์ ์๋ต์ ์คํธ๋ฆฌ๋ฐํ๊ณ ๋์ฐฉํ๋ ๋๋ก ๊ฐ ์ฒญํฌ๋ฅผ ์ธ์ํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ํนํ ์ฑํ ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ ์ฌ์ฉ์์๊ฒ ์ค์๊ฐ ํผ๋๋ฐฑ์ ์ ๊ณตํ๋ ค๋ ๋ชจ๋ ์๋๋ฆฌ์ค์ ์ ์ฉํฉ๋๋ค.
LangChain์ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ์ํฌํ๋ก ๊ตฌ์ถ
๋ ๋ณต์กํ LLM ๊ธฐ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ LangChain ํ๋ ์์ํฌ ์ฌ๋ฌ LLM ํธ์ถ์ ์ฒด์ธ์ผ๋ก ์ฐ๊ฒฐํ๊ณ ๋ค๋ฅธ ๋๊ตฌ๋ฅผ ํตํฉํ๋ ๊ณผ์ ์ ๊ฐ์ํํ๋ ๊ณ ์์ค ์ถ์ํ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋น๋๊ธฐ ๊ธฐ๋ฅ์ ๊ฐ์ถ LangChain์ ์ฌ์ฉํ๋ ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ด ์์์๋ LangChain์ ์ฌ์ฉํ์ฌ ์คํธ๋ฆฌ๋ฐ ๋ฐ ๋น๋๊ธฐ ์คํ์ ํตํด ๋ ๋ณต์กํ ์ํฌํ๋ก๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. AsyncCallbackManager
๊ทธ๋ฆฌ๊ณ StreamingStdOutCallbackHandler
์์ฑ๋ ์ฝํ
์ธ ์ ์ค์๊ฐ ์คํธ๋ฆฌ๋ฐ์ ํ์ฑํํฉ๋๋ค.
import asyncio from langchain.llms import OpenAI from langchain.prompts import PromptTemplate from langchain.chains import LLMChain from langchain.callbacks.manager import AsyncCallbackManager from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler async def generate_story(topic): llm = OpenAI(temperature=0.7, streaming=True, callback_manager=AsyncCallbackManager([StreamingStdOutCallbackHandler()])) prompt = PromptTemplate( input_variables=["topic"], template="Write a short story about {topic}." ) chain = LLMChain(llm=llm, prompt=prompt) return await chain.arun(topic=topic) async def main(): topics = ["a magical forest", "a futuristic city", "an underwater civilization"] tasks = [generate_story(topic) for topic in topics] stories = await asyncio.gather(*tasks) for topic, story in zip(topics, stories): print(f"\nTopic: {topic}\nStory: {story}\n{'='*50}\n") asyncio.run(main())
FastAPI๋ฅผ ์ฌ์ฉํ ๋น๋๊ธฐ LLM ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ณต
๋น๋๊ธฐ LLM ์ ํ๋ฆฌ์ผ์ด์ ์ ์น ์๋น์ค๋ก ์ ๊ณตํ๋ ค๋ฉด ๋น๋๊ธฐ ์์ ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์ํ๋ FastAPI๊ฐ ๋งค์ฐ ์ ํฉํฉ๋๋ค. ๋ค์์ ํ ์คํธ ์์ฑ์ ์ํ ๊ฐ๋จํ API ์๋ํฌ์ธํธ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์์ ๋๋ค.
from fastapi import FastAPI, BackgroundTasks from pydantic import BaseModel from openai import AsyncOpenAI app = FastAPI() client = AsyncOpenAI() class GenerationRequest(BaseModel): prompt: str class GenerationResponse(BaseModel): generated_text: str @app.post("/generate", response_model=GenerationResponse) async def generate_text(request: GenerationRequest, background_tasks: BackgroundTasks): response = await client.chat.completions.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": request.prompt}] ) generated_text = response.choices[0].message.content # Simulate some post-processing in the background background_tasks.add_task(log_generation, request.prompt, generated_text) return GenerationResponse(generated_text=generated_text) async def log_generation(prompt: str, generated_text: str): # Simulate logging or additional processing await asyncio.sleep(2) print(f"Logged: Prompt '{prompt}' generated text of length {len(generated_text)}") if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
์ด FastAPI ์ ํ๋ฆฌ์ผ์ด์
์ ์๋ํฌ์ธํธ๋ฅผ ์์ฑํฉ๋๋ค. /generate
ํ๋กฌํํธ๋ฅผ ๋ฐ์๋ค์ด๊ณ ์์ฑ๋ ํ
์คํธ๋ฅผ ๋ฐํํ๋ ๊ฒ์
๋๋ค. ๋ํ ์๋ต์ ์ฐจ๋จํ์ง ์๊ณ ์ถ๊ฐ ์ฒ๋ฆฌ๋ฅผ ์ํด ๋ฐฑ๊ทธ๋ผ์ด๋ ์์
์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ๋ณด์ฌ์ค๋๋ค.
๋ชจ๋ฒ ์ฌ๋ก ๋ฐ ์ผ๋ฐ์ ์ธ ํจ์
๋น๋๊ธฐ LLM API๋ฅผ ์ฌ์ฉํ ๋ ๋ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ผ๋์ ๋์ญ์์ค.
- ์ฐ๊ฒฐ ํ๋ง ์ฌ์ฉ: ์ฌ๋ฌ ์์ฒญ์ ํ๋ ๊ฒฝ์ฐ, ์ค๋ฒํค๋๋ฅผ ์ค์ด๊ธฐ ์ํด ์ฐ๊ฒฐ์ ์ฌ์ฌ์ฉํฉ๋๋ค.
- ์ ์ ํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ์ธ์: ๋คํธ์ํฌ ๋ฌธ์ , API ์ค๋ฅ, ์์์น ๋ชปํ ์๋ต์ ํญ์ ๋๋นํ์ธ์.
- ์๊ธ ์ ํ์ ์กด์คํ์ธ์: API์ ๊ณผ๋ถํ๊ฐ ๊ฑธ๋ฆฌ๋ ๊ฒ์ ๋ฐฉ์งํ๋ ค๋ฉด ์ธ๋งํฌ์ด๋ ๊ธฐํ ๋์์ฑ ์ ์ด ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํ์ธ์.
- ๋ชจ๋ํฐ ๋ฐ ๊ธฐ๋ก: ์ฑ๋ฅ์ ์ถ์ ํ๊ณ ๋ฌธ์ ๋ฅผ ์๋ณํ๊ธฐ ์ํด ํฌ๊ด์ ์ธ ๋ก๊น ์ ๊ตฌํํฉ๋๋ค.
- ์ฅํธ ์ฝํ ์ธ ์๋ ์คํธ๋ฆฌ๋ฐ์ ์ฌ์ฉํ์ธ์: ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํค๊ณ ๋ถ๋ถ์ ์ธ ๊ฒฐ๊ณผ์ ์กฐ๊ธฐ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.