Ver3.0 ๐ Ollama๋ก ๋ก์ปฌ LLM ์คํํ๊ธฐ

๐ Ollama๋ก ๋ก์ปฌ LLM ์คํํ๊ธฐ
๋ด ์ปดํจํฐ์์ AI๋ฅผ ๋๋ ค๋ณด์! ํด๋ผ์ฐ๋ ์์ด๋ ๊ฐ๋ฅํ ๋ก์ปฌ AI์ ์ธ๊ณ ๐ฏ
๐ช ์ ๋ก์ปฌ์์ LLM์ ๋๋ ค์ผ ํ ๊น?
์์ฆ ChatGPT๋ Claude ๊ฐ์ AI ์๋น์ค๋ค์ด ์ ๋ง ๋๋จํ์์? ๊ทผ๋ฐ ์ด๋ฐ ์๋น์ค๋ค์ ๋ชจ๋ ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ์ด์ผ. ๋ด๊ฐ ์ ๋ ฅํ ๋ฐ์ดํฐ๊ฐ ์ธํฐ๋ท์ ํตํด ์๋ฒ๋ก ์ ์ก๋๊ณ , ๊ฑฐ๊ธฐ์ ์ฒ๋ฆฌ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ๋ฐ์์ค๋ ๊ตฌ์กฐ์ง. ๐๊ทธ๋ฐ๋ฐ ๋ง์ด์ผ, ์ด๋ฐ ๋ฐฉ์์๋ ๋ช ๊ฐ์ง ๋ฌธ์ ๊ฐ ์์ด:
ํ๋ผ์ด๋ฒ์ ๋ฌธ์ - ๋ฏผ๊ฐํ ํ์ฌ ๋ฐ์ดํฐ๋ ๊ฐ์ธ์ ๋ณด๋ฅผ ์ธ๋ถ ์๋ฒ๋ก ๋ณด๋ด๋ ๊ฒ ๋ถ์ํ ์ ์์ด. ํนํ ์๋ฃ, ๊ธ์ต, ๋ฒ๋ฅ ๋ถ์ผ์์๋ ๋ฐ์ดํฐ ์ ์ถ์ด ์น๋ช ์ ์ด๊ฑฐ๋ .
๋น์ฉ ๋ฌธ์ - API ํธ์ถํ ๋๋ง๋ค ๋์ด ๋๊ฐ. ๊ฐ๋ฐํ๋ฉด์ ํ ์คํธ ๋ง์ด ํ๋ค ๋ณด๋ฉด ๋น์ฉ์ด ๋๋ฉ์ด์ฒ๋ผ ๋ถ์ด๋๋ ๊ฒฝํ, ๋ค๋ค ํด๋ดค์ ๊ฑฐ์ผ. ๐ธ
์ธํฐ๋ท ์์กด์ฑ - ๋คํธ์ํฌ๊ฐ ๋๊ธฐ๋ฉด? ๊ทธ๋ฅ ์์ ์ค๋จ์ด์ผ. ๋นํ๊ธฐ ์์ด๋ ์ค์ง์์๋ ์ฌ์ฉํ ์ ์์ง.
์๋ต ์๋ - ๋คํธ์ํฌ ์๋ณต ์๊ฐ์ด ์ถ๊ฐ๋๋๊น ๋ก์ปฌ๋ณด๋ค ๋๋ฆด ์๋ฐ์ ์์ด.
๊ทธ๋์ ๋ฑ์ฅํ ๊ฒ ๋ฐ๋ก ๋ก์ปฌ LLM์ด์ผ! ๋ด ์ปดํจํฐ์ AI ๋ชจ๋ธ์ ์ง์ ์ค์นํด์ ๋๋ฆฌ๋ ๊ฑฐ์ง. ๊ทธ๋ฆฌ๊ณ ์ด๊ฑธ ๊ฐ์ฅ ์ฝ๊ฒ ํด์ฃผ๋ ๋๊ตฌ๊ฐ ๋ฐ๋ก Ollama์ผ. ๐
๐ฆ Ollama๊ฐ ๋ญ๊ธธ๋?
๐ Ollama์ ํต์ฌ ํน์ง
๋ณต์กํ Python ํ๊ฒฝ ์ค์ ์ด๋ CUDA ๋๋ผ์ด๋ฒ ์ค์น ๊ฐ์ ๊ณจ์น ์ํ ์์ ์ด ํ์ ์์ด. ๊ทธ๋ฅ ์ค์น ํ์ผ ํ๋ ๋ค์ด๋ก๋ํ๊ณ ์คํํ๋ฉด ๋! ๋ง์น ๊ฒ์ ์ค์นํ๋ฏ์ด ์ฌ์. ๐ฎ
Llama 2, Mistral, Phi, Gemma ๋ฑ ์์ญ ๊ฐ์ง ์คํ์์ค ๋ชจ๋ธ์ ์ง์ํด. ๋ชจ๋ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ํ๋ ๊ฑธ ๊ณจ๋ผ์ ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ง. ๋ชจ๋ธ ํฌ๊ธฐ๋ 7B๋ถํฐ 70B๊น์ง ๋ค์ํด์ ๋ด ํ๋์จ์ด ์ฌ์์ ๋ง์ถฐ ์ ํํ ์ ์์ด.
Ollama๋ฅผ ์คํํ๋ฉด ์๋์ผ๋ก REST API ์๋ฒ๊ฐ ๋์์ ธ. ๊ทธ๋์ Python, JavaScript, Go ๋ฑ ์ด๋ค ์ธ์ด๋ก๋ ์ฝ๊ฒ ์ฐ๋ํ ์ ์์ด. OpenAI API์ ํธํ๋๋ ์๋ํฌ์ธํธ๋ ์ ๊ณตํด์ ๊ธฐ์กด ์ฝ๋๋ฅผ ๊ฑฐ์ ์์ ์์ด ์ฌ์ฉํ ์ ์์ง. ๐
Modelfile์ด๋ผ๋ ์ค์ ํ์ผ๋ก ๋ชจ๋ธ์ ๋์์ ์ธ๋ฐํ๊ฒ ์กฐ์ ํ ์ ์์ด. ์์คํ ํ๋กฌํํธ, ์จ๋(temperature), ์ปจํ ์คํธ ๊ธธ์ด ๋ฑ์ ๋ด ์ ๋ง๋๋ก ๋ฐ๊ฟ ์ ์์ง.
macOS, Linux, Windows ๋ชจ๋ ์ง์ํด. ํนํ macOS์์๋ Apple Silicon(M1/M2/M3)์ Neural Engine์ ํ์ฉํด์ ๋๋ผ์ด ์ฑ๋ฅ์ ๋ณด์ฌ์ค. ๐
โ๏ธ Ollama ์ค์นํ๊ธฐ
์, ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก Ollama๋ฅผ ์ค์นํด๋ณด์! ์ด์์ฒด์ ๋ณ๋ก ์ค๋ช ํ ๊ฒ. ๐๐ macOS ์ค์น
Ollama ๊ณต์ ์น์ฌ์ดํธ(ollama.ai)์ ์ ์ํด์ macOS์ฉ ์ค์น ํ์ผ์ ๋ค์ด๋ก๋ํด. .dmg ํ์ผ์ด ๋ฐ์์ง ๊ฑฐ์ผ.
๋ค์ด๋ก๋ํ .dmg ํ์ผ์ ์ด๊ณ Ollama ์์ด์ฝ์ Applications ํด๋๋ก ๋๋๊ทธํด. ์ผ๋ฐ์ ์ธ Mac ์ฑ ์ค์น ๋ฐฉ์์ด์ผ.
Applications ํด๋์์ Ollama๋ฅผ ์คํํด. ๋ฉ๋ด๋ฐ์ ๋ผ๋ง ์์ด์ฝ์ด ๋ํ๋๋ฉด ์ฑ๊ณต! ๐ฆ
๐ง Linux ์ค์น
Linux๋ ํฐ๋ฏธ๋ ํ ์ค์ด๋ฉด ๋์ด์ผ:curl -fsSL https://ollama.ai/install.sh | sh
์ด ์คํฌ๋ฆฝํธ๊ฐ ์๋์ผ๋ก ํ์ํ ๋ชจ๋ ๊ฑธ ์ค์นํด์ค. systemd ์๋น์ค๋ก ๋ฑ๋ก๋์ด์ ๋ถํ
์ ์๋์ผ๋ก ์์๋ผ.๐ช Windows ์ค์น
Ollama ์น์ฌ์ดํธ์์ Windows์ฉ ์ค์น ํ์ผ(.exe)์ ๋ค์ด๋ก๋ํด.
๋ค์ด๋ก๋ํ ํ์ผ์ ์คํํ๊ณ ์ค์น ๋ง๋ฒ์ฌ๋ฅผ ๋ฐ๋ผ๊ฐ. Next ๋ฒํผ๋ง ๋ช ๋ฒ ๋๋ฅด๋ฉด ๋ผ.
์์คํ ํธ๋ ์ด์ Ollama ์์ด์ฝ์ด ๋ํ๋๋ฉด ์ค์น ์๋ฃ!
โ ์ค์น ํ์ธ
์ค์น๊ฐ ์ ๋๋ก ๋๋์ง ํ์ธํด๋ณด์. ํฐ๋ฏธ๋(๋๋ ๋ช ๋ น ํ๋กฌํํธ)์ ์ด๊ณ :ollama --version
๋ฒ์ ์ ๋ณด๊ฐ ๋์ค๋ฉด ์ฑ๊ณต! ์๋ฅผ ๋ค์ด ์ด๋ฐ ์์ผ๋ก ๋์ฌ ๊ฑฐ์ผ:๐ ์ฒซ ๋ฒ์งธ ๋ชจ๋ธ ์คํํ๊ธฐ
์ค์น๊ฐ ๋๋ฌ์ผ๋ ์ด์ ์ง์ง ์ฌ๋ฏธ์๋ ๋ถ๋ถ์ด์ผ! ์ฒซ ๋ฒ์งธ AI ๋ชจ๋ธ์ ์คํํด๋ณด์. ๐๐ฏ Llama 2 ์คํํ๊ธฐ
๊ฐ์ฅ ์ธ๊ธฐ ์๋ ๋ชจ๋ธ ์ค ํ๋์ธ Llama 2๋ฅผ ์คํํด๋ณผ๊ฒ. ํฐ๋ฏธ๋์์ ์ด๋ ๊ฒ ์ ๋ ฅํด:ollama run llama2
์ด ๋ช
๋ น์ด๋ฅผ ์คํํ๋ฉด ์ฌ๋ฌ ์ผ์ด ๋์์ ์ผ์ด๋:1๋จ๊ณ: ๋ชจ๋ธ ๋ค์ด๋ก๋
์ฒ์ ์คํํ๋ฉด ๋ชจ๋ธ ํ์ผ์ ๋ค์ด๋ก๋ํด. Llama 2 7B ๋ชจ๋ธ์ ์ฝ 3.8GB ์ ๋์ผ. ์ธํฐ๋ท ์๋์ ๋ฐ๋ผ ๋ช ๋ถ ์ ๋ ๊ฑธ๋ฆด ์ ์์ด.
pulling 8934d96d3f08... 100% โโโโโโโโโโโโโโโโโโ 3.8 GB
pulling 8c17c2ebb0ea... 100% โโโโโโโโโโโโโโโโโโ 7.0 KB
pulling 7c23fb36d801... 100% โโโโโโโโโโโโโโโโโโ 4.8 KB
pulling 2e0493f67d0c... 100% โโโโโโโโโโโโโโโโโโ 59 B
verifying sha256 digest
writing manifest
success
๋ค์ด๋ก๋๊ฐ ๋๋๋ฉด ๋ชจ๋ธ์ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋ํด. ์ด ๊ณผ์ ๋ ๋ช ์ด ์ ๋ ๊ฑธ๋ ค.
3๋จ๊ณ: ๋ํ ์์!
ํ๋กฌํํธ๊ฐ ๋ํ๋๋ฉด ์ด์ AI์ ๋ํํ ์ ์์ด! ๐
>>> ์๋
? ๋๋ ๋๊ตฌ์ผ?
์๋
ํ์ธ์! ์ ๋ Llama 2๋ผ๊ณ ํ๋ AI ์ด์์คํดํธ์
๋๋ค.
Meta์์ ๊ฐ๋ฐํ ๋ํ ์ธ์ด ๋ชจ๋ธ์ด์์. ์ง๋ฌธ์ ๋ตํ๊ณ ,
์ ๋ณด๋ฅผ ์ ๊ณตํ๊ณ , ๋ํ๋ฅผ ๋๋๋ ๊ฒ์ ๋์๋๋ฆด ์ ์์ต๋๋ค.
๋ฌด์์ ๋์๋๋ฆด๊น์?
llama2:7b(๊ธฐ๋ณธ), llama2:13b, llama2:70b ๋ฑ์ด ์์ด. ์ซ์๊ฐ ํด์๋ก ์ฑ๋ฅ์ ์ข์ง๋ง ๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ์ํด. ์ผ๋ฐ์ ์ผ๋ก 7B ๋ชจ๋ธ์ 8GB RAM, 13B๋ 16GB, 70B๋ 64GB ์ ๋ ํ์ํด.
๐ ๋ค๋ฅธ ๋ชจ๋ธ๋ค ์๋ํด๋ณด๊ธฐ
Ollama๋ ์ ๋ง ๋ค์ํ ๋ชจ๋ธ์ ์ง์ํด. ๋ช ๊ฐ์ง ์ถ์ฒํ ๊ฒ:7B ํ๋ผ๋ฏธํฐ์ง๋ง ์ฑ๋ฅ์ด ์ ๋ง ๋ฐ์ด๋. Llama 2 13B์ ๋น์ทํ ์ฑ๋ฅ์ ๋ณด์ฌ์ค. ํจ์จ์ฑ์ด ์ค์ํ๋ค๋ฉด ์ด๊ฑธ ์ถ์ฒ!
ollama run mistral
Microsoft์์ ๋ง๋ ์์ ๋ชจ๋ธ(2.7B)์ด์ผ. ํฌ๊ธฐ๋ ์์ง๋ง ๋๋ผ์ด ์ฑ๋ฅ์ ๋ณด์ฌ์ค. ์ ์ฌ์ ์ปดํจํฐ์ ๋ฑ์ด์ผ!
ollama run phi
์ฝ๋ฉ์ ํนํ๋ ๋ชจ๋ธ์ด์ผ. ํ๋ก๊ทธ๋๋ฐ ์ง๋ฌธ์ด๋ ์ฝ๋ ์์ฑ์ ์ต์ ํ๋์ด ์์ด. ๊ฐ๋ฐ์๋ผ๋ฉด ํ์! ๐จโ๐ป
ollama run codellama
Google์์ ๊ณต๊ฐํ ์ต์ ๋ชจ๋ธ์ด์ผ. 2B์ 7B ๋ฒ์ ์ด ์๊ณ , ์ฑ๋ฅ ๋๋น ํจ์จ์ด ์ ๋ง ์ข์.
ollama run gemma:7b
๐ฎ ๋ํ ๋ชจ๋ ์ฌ์ฉํ๊ธฐ
ollama run ๋ช
๋ น์ด๋ ๋ํํ ๋ชจ๋๋ก ์คํ๋ผ. ์ฌ๊ธฐ์ ์ฌ์ฉํ ์ ์๋ ํน์ ๋ช
๋ น์ด๋ค์ด ์์ด:/bye - ๋ํ ์ข ๋ฃ
/clear - ๋ํ ๊ธฐ๋ก ์ด๊ธฐํ
/show - ๋ชจ๋ธ ์ ๋ณด ํ์
/set parameter value - ํ๋ผ๋ฏธํฐ ์กฐ์
์๋ฅผ ๋ค์ด, ์๋ต์ ์ฐฝ์์ฑ์ ๋์ด๊ณ ์ถ๋ค๋ฉด:
>>> /set temperature 0.9
Temperature๋ 0~1 ์ฌ์ด ๊ฐ์ด์ผ. ๋์์๋ก ๋ ์ฐฝ์์ ์ด๊ณ ๋ค์ํ ๋ต๋ณ์, ๋ฎ์์๋ก ๋ ์ผ๊ด๋๊ณ ์์ธก ๊ฐ๋ฅํ ๋ต๋ณ์ ์์ฑํด. ๐
๐ ๏ธ API๋ก Ollama ์ฌ์ฉํ๊ธฐ
๋ํํ ๋ชจ๋๋ ์ข์ง๋ง, ์ง์ง ํ์๋ API๋ฅผ ํตํด ํ๋ก๊ทธ๋๋ฐ์ ์ผ๋ก ์ฌ์ฉํ ๋ ๋์! Ollama๋ REST API๋ฅผ ์ ๊ณตํด์ ์ด๋ค ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ก๋ ์ฝ๊ฒ ํตํฉํ ์ ์์ด. ๐๐ ๊ธฐ๋ณธ API ๊ตฌ์กฐ
Ollama๋ฅผ ์คํํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋กhttp://localhost:11434์์ API ์๋ฒ๊ฐ ๋์ํด. ์ฃผ์ ์๋ํฌ์ธํธ๋ ์ด๋ ๊ฒ ๊ตฌ์ฑ๋ผ:POST /api/chat - ๋ํํ ์ฑํ
POST /api/embeddings - ์๋ฒ ๋ฉ ๋ฒกํฐ ์์ฑ
GET /api/tags - ์ค์น๋ ๋ชจ๋ธ ๋ชฉ๋ก
POST /api/pull - ๋ชจ๋ธ ๋ค์ด๋ก๋
DELETE /api/delete - ๋ชจ๋ธ ์ญ์
๐ Python์ผ๋ก ์ฌ์ฉํ๊ธฐ
Python์์ ์ฌ์ฉํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฑฐ์ผ:pip install ollama
์ค์น ํ ์ด๋ ๊ฒ ์ฌ์ฉํ ์ ์์ด:import ollama
response = ollama.chat(model='llama2', messages=[
{
'role': 'user',
'content': 'Python์ผ๋ก ํผ๋ณด๋์น ์์ด์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์๋ ค์ค',
},
])
print(response['message']['content'])
์คํธ๋ฆฌ๋ฐ ์๋ต์ ๋ฐ๊ณ ์ถ๋ค๋ฉด:import ollama
stream = ollama.chat(
model='llama2',
messages=[{'role': 'user', 'content': '๊ธด ์ด์ผ๊ธฐ๋ฅผ ๋ค๋ ค์ค'}],
stream=True,
)
for chunk in stream:
print(chunk['message']['content'], end='', flush=True)
์ด๋ ๊ฒ ํ๋ฉด ChatGPT์ฒ๋ผ ๊ธ์๊ฐ ํ๋์ฉ ๋ํ๋๋ ํจ๊ณผ๋ฅผ ๋ง๋ค ์ ์์ด! โจ๐จ JavaScript/Node.js๋ก ์ฌ์ฉํ๊ธฐ
JavaScript์์๋ ๋๊ฐ์ด ์ฌ์:npm install ollama
import ollama from 'ollama'
const response = await ollama.chat({
model: 'llama2',
messages: [{ role: 'user', content: 'JavaScript๋ ์ ์ธ๊ธฐ๊ฐ ๋ง์๊น?' }],
})
console.log(response.message.content)
์คํธ๋ฆฌ๋ฐ๋ ์ง์ํด:const response = await ollama.chat({
model: 'llama2',
messages: [{ role: 'user', content: '๊ธด ์ด์ผ๊ธฐ๋ฅผ ๋ค๋ ค์ค' }],
stream: true,
})
for await (const part of response) {
process.stdout.write(part.message.content)
}
๐ REST API ์ง์ ํธ์ถํ๊ธฐ
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ด ์ง์ HTTP ์์ฒญ์ ๋ณด๋ผ ์๋ ์์ด. curl๋ก ์๋ฅผ ๋ค๋ฉด:curl http://localhost:11434/api/generate -d '{
"model": "llama2",
"prompt": "ํ๋์ ์ ํ๋์์ผ๊น?",
"stream": false
}'
์๋ต์ JSON ํํ๋ก ์:{
"model": "llama2",
"created_at": "2024-01-15T09:30:00.123456Z",
"response": "ํ๋์ด ํ๋์์ผ๋ก ๋ณด์ด๋ ์ด์ ๋...",
"done": true
}
http://localhost:11434/v1/chat/completions๋ฅผ ์ฌ์ฉํ๋ฉด ๋ผ.
๐จ Modelfile๋ก ์ปค์คํ ๋ชจ๋ธ ๋ง๋ค๊ธฐ
Ollama์ ์ง์ง ๊ฐ๋ ฅํ ๊ธฐ๋ฅ ์ค ํ๋๊ฐ ๋ฐ๋ก Modelfile์ด์ผ. Docker์ Dockerfile์ฒ๋ผ, Modelfile์ ์ฌ์ฉํ๋ฉด ๊ธฐ์กด ๋ชจ๋ธ์ ๊ธฐ๋ฐ์ผ๋ก ๋๋ง์ ์ปค์คํ ๋ชจ๋ธ์ ๋ง๋ค ์ ์์ด! ๐ฏ๐ Modelfile ๊ธฐ๋ณธ ๊ตฌ์กฐ
Modelfile์ ๊ฐ๋จํ ํ ์คํธ ํ์ผ์ด์ผ. ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ๋ณด์:FROM llama2
PARAMETER temperature 0.8
PARAMETER top_p 0.9
SYSTEM """
๋น์ ์ ์น์ ํ ํ๊ตญ์ด AI ์ด์์คํดํธ์
๋๋ค.
ํญ์ ์กด๋๋ง์ ์ฌ์ฉํ๊ณ , ์์ธํ๊ณ ์ ํํ ๋ต๋ณ์ ์ ๊ณตํฉ๋๋ค.
"""
TEMPLATE """{{ .System }}
์ฌ์ฉ์: {{ .Prompt }}
์ด์์คํดํธ: """
๊ฐ ๋ถ๋ถ์ ์ค๋ช
ํด๋ณผ๊ฒ:๋ฒ ์ด์ค ๋ชจ๋ธ์ ์ง์ ํด. ๊ธฐ์กด์ ๋ค์ด๋ก๋ํ ๋ชจ๋ธ์ด๋ Ollama ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ชจ๋ธ์ ์ฌ์ฉํ ์ ์์ด.
๋ชจ๋ธ์ ๋์์ ์ ์ดํ๋ ํ๋ผ๋ฏธํฐ๋ค์ ์ค์ ํด. ์ฃผ์ ํ๋ผ๋ฏธํฐ๋ค:
โข temperature (0.0-2.0): ์๋ต์ ๋ฌด์์์ฑ. ๋์์๋ก ์ฐฝ์์
โข top_p (0.0-1.0): ๋์ ํ๋ฅ ์๊ณ๊ฐ
โข top_k (์ ์): ๊ณ ๋ คํ ํ ํฐ ์
โข num_ctx (์ ์): ์ปจํ ์คํธ ์๋์ฐ ํฌ๊ธฐ
โข repeat_penalty (1.0+): ๋ฐ๋ณต ์ต์ ๊ฐ๋
์์คํ ํ๋กฌํํธ๋ฅผ ์ ์ํด. ๋ชจ๋ธ์ ํ๋ฅด์๋๋ ํ๋ ๋ฐฉ์์ ์ง์ ํ๋ ๊ฑฐ์ผ. ์ด๊ฒ ์ ๋ง ์ค์ํด!
ํ๋กฌํํธ ํ ํ๋ฆฟ์ ์ ์ํด. ์ฌ์ฉ์ ์ ๋ ฅ์ด ์ด๋ป๊ฒ ๋ชจ๋ธ์ ์ ๋ฌ๋ ์ง ๊ตฌ์กฐ๋ฅผ ๋ง๋๋ ๊ฑฐ์ผ.
๐ ์ค์ ์์ : ์ฝ๋ฉ ์ด์์คํดํธ ๋ง๋ค๊ธฐ
์ค์ ๋ก ์ ์ฉํ ์ปค์คํ ๋ชจ๋ธ์ ๋ง๋ค์ด๋ณด์. ์ฝ๋ฉ์ ํนํ๋ ์ด์์คํดํธ์ผ:# Modelfile
FROM codellama:7b
PARAMETER temperature 0.3
PARAMETER top_p 0.9
PARAMETER num_ctx 4096
SYSTEM """
๋น์ ์ ์ ๋ฌธ ํ๋ก๊ทธ๋๋ฐ ์ด์์คํดํธ์
๋๋ค.
์ญํ :
- ์ฝ๋ ์์ฑ, ๋ฆฌ๋ทฐ, ๋๋ฒ๊น
์ง์
- ์๊ณ ๋ฆฌ์ฆ๊ณผ ์๋ฃ๊ตฌ์กฐ ์ค๋ช
- ๋ฒ ์คํธ ํ๋ํฐ์ค ์ ์
- ์ฑ๋ฅ ์ต์ ํ ์กฐ์ธ
๋ต๋ณ ๊ท์น:
1. ์ฝ๋๋ ๋ฐ๋์ ์ฃผ์๊ณผ ํจ๊ป ์ ๊ณต
2. ์ฌ๋ฌ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์๋ค๋ฉด ์ฅ๋จ์ ๋น๊ต
3. ์คํ ๊ฐ๋ฅํ ์์ ํ ์์ ์ ๊ณต
4. ๋ณด์๊ณผ ์ฑ๋ฅ์ ํญ์ ๊ณ ๋ ค
"""
TEMPLATE """{{ .System }}
## ์ง๋ฌธ
{{ .Prompt }}
## ๋ต๋ณ
"""
์ด Modelfile์ Modelfile.coding์ด๋ผ๋ ์ด๋ฆ์ผ๋ก ์ ์ฅํ๊ณ , ๋ค์ ๋ช
๋ น์ด๋ก ๋ชจ๋ธ์ ์์ฑํด:ollama create my-coding-assistant -f Modelfile.coding
์ด์ ์ฌ์ฉํ ์ ์์ด:ollama run my-coding-assistant
๐ผ ์ค์ ์์ : ๋น์ฆ๋์ค ๋ถ์๊ฐ
๋ค๋ฅธ ์์ ๋ ๋ณด์. ๋น์ฆ๋์ค ๋ฐ์ดํฐ ๋ถ์์ ํนํ๋ ๋ชจ๋ธ์ด์ผ:FROM mistral
PARAMETER temperature 0.5
PARAMETER top_p 0.95
SYSTEM """
๋น์ ์ ๋ฐ์ดํฐ ๊ธฐ๋ฐ ๋น์ฆ๋์ค ๋ถ์ ์ ๋ฌธ๊ฐ์
๋๋ค.
์ ๋ฌธ ๋ถ์ผ:
- ๋ฐ์ดํฐ ๋ถ์ ๋ฐ ์๊ฐํ
- ๋น์ฆ๋์ค ์ธ์ฌ์ดํธ ๋์ถ
- KPI ์ค์ ๋ฐ ๋ชจ๋ํฐ๋ง
- ์์ฌ๊ฒฐ์ ์ง์
๋ต๋ณ ์คํ์ผ:
- ๋ฐ์ดํฐ ๊ธฐ๋ฐ ๊ฐ๊ด์ ๋ถ์
- ๋ช
ํํ ์์น์ ๊ทผ๊ฑฐ ์ ์
- ์คํ ๊ฐ๋ฅํ ์ก์
์์ดํ
์ ์
- ๋น์ฆ๋์ค ์ฉ์ด ์ฌ์ฉ
"""
๐ญ ์ค์ ์์ : ์ฐฝ์์ ์๊ฐ
์ฐฝ์์ ์ธ ๊ธ์ฐ๊ธฐ๋ฅผ ๋๋ ๋ชจ๋ธ๋ ๋ง๋ค ์ ์์ด:FROM llama2
PARAMETER temperature 1.2
PARAMETER top_p 0.95
PARAMETER repeat_penalty 1.2
SYSTEM """
๋น์ ์ ์ฐฝ์์ ์ธ ์๊ฐ์ด์ ์คํ ๋ฆฌํ
๋ฌ์
๋๋ค.
ํน๊ธฐ:
- ํฅ๋ฏธ์ง์งํ ์ด์ผ๊ธฐ ์ฐฝ์
- ์์ํ ๋ฌ์ฌ์ ๊ฐ์ ํํ
- ๋
์ฐฝ์ ์ธ ์์ด๋์ด ์ ์
- ๋ค์ํ ์ฅ๋ฅด ๊ธ์ฐ๊ธฐ
๊ธ์ฐ๊ธฐ ์์น:
- ๋
์์ ๊ฐ์ ์ ์์ง์ด๋ ์์ฌ
- ๊ตฌ์ฒด์ ์ด๊ณ ๊ฐ๊ฐ์ ์ธ ๋ฌ์ฌ
- ์์์ ๋ค์๋ ์ ๊ฐ
- ์บ๋ฆญํฐ์ ๊น์ด ์๋ ์ฌ๋ฆฌ ๋ฌ์ฌ
"""
โข 0.1-0.3: ์ฌ์ค์ ์ ๋ณด, ์ฝ๋, ๋ฒ์ญ (์ผ๊ด์ฑ ์ค์)
โข 0.5-0.7: ์ผ๋ฐ์ ์ธ ๋ํ, ์ค๋ช (๊ท ํ)
โข 0.8-1.0: ๋ธ๋ ์ธ์คํ ๋ฐ, ์์ด๋์ด (๋ค์์ฑ)
โข 1.1-2.0: ์ฐฝ์์ ๊ธ์ฐ๊ธฐ, ์์ (์ฐฝ์์ฑ ๊ทน๋ํ)
๐ง ๊ณ ๊ธ ๊ธฐ๋ฅ: ์ด๋ํฐ ์ฌ์ฉํ๊ธฐ
LoRA(Low-Rank Adaptation) ์ด๋ํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ชจ๋ธ์ ํน์ ์์ ์ ํ์ธํ๋ํ ์ ์์ด:FROM llama2
ADAPTER ./my-lora-adapter.bin
PARAMETER temperature 0.7
์ด๊ฑด ์ข ๋ ๊ณ ๊ธ ๊ธฐ๋ฅ์ด๋ผ ๋ณ๋๋ก ๋ชจ๋ธ ํ์ต์ด ํ์ํด. ํ์ง๋ง ํน์ ๋๋ฉ์ธ(์๋ฃ, ๋ฒ๋ฅ ๋ฑ)์ ํนํ๋ ๋ชจ๋ธ์ ๋ง๋ค ๋ ์ ๋ง ์ ์ฉํด! ๐
โก ์ฑ๋ฅ ์ต์ ํ ํ
๋ก์ปฌ์์ LLM์ ๋๋ฆฌ๋ค ๋ณด๋ฉด ์ฑ๋ฅ์ด ์ค์ํด์ง์ง. ๋ช ๊ฐ์ง ์ต์ ํ ํ์ ๊ณต์ ํ ๊ฒ! ๐๐พ ํ๋์จ์ด ์ต์ ํ
NVIDIA GPU๊ฐ ์๋ค๋ฉด CUDA๋ฅผ ํตํด ์๋์ผ๋ก ๊ฐ์๋ผ. GPU ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ถฉ๋ถํ๋ฉด CPU๋ณด๋ค 10-50๋ฐฐ ๋น ๋ฅผ ์ ์์ด!
GPU ์ฌ์ฉ ํ์ธ:
ollama ps ๋ช
๋ น์ด๋ก ํ์ฌ ์คํ ์ค์ธ ๋ชจ๋ธ๊ณผ GPU ์ฌ์ฉ๋์ ๋ณผ ์ ์์ด.
๋ชจ๋ธ ํฌ๊ธฐ์ ๋ฐ๋ผ ํ์ํ RAM:
โข 7B ๋ชจ๋ธ: ์ต์ 8GB (๊ถ์ฅ 16GB)
โข 13B ๋ชจ๋ธ: ์ต์ 16GB (๊ถ์ฅ 32GB)
โข 30B ๋ชจ๋ธ: ์ต์ 32GB (๊ถ์ฅ 64GB)
โข 70B ๋ชจ๋ธ: ์ต์ 64GB (๊ถ์ฅ 128GB)
๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ๋ฉด ์ค์์ ์ฌ์ฉํ๊ฒ ๋์ด ์์ฒญ ๋๋ ค์ ธ. ๐ฐ
Ollama๋ ๊ธฐ๋ณธ์ ์ผ๋ก 4-bit ์์ํ๋ ๋ชจ๋ธ์ ์ฌ์ฉํด. ์ด๊ฒ ๋ญ๋๋ฉด, ๋ชจ๋ธ์ ๊ฐ์ค์น๋ฅผ ์์ถํด์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ๊ฒ ์ฐ๋ฉด์๋ ์ฑ๋ฅ์ ๊ฑฐ์ ์ ์งํ๋ ๊ธฐ์ ์ด์ผ.
๋ค์ํ ์์ํ ๋ฒ์ :
โข Q4_0: ๊ฐ์ฅ ์๊ณ ๋น ๋ฆ (๊ธฐ๋ณธ)
โข Q5_K_M: ์ค๊ฐ ํฌ๊ธฐ, ์ข์ ํ์ง
โข Q8_0: ํฐ ํฌ๊ธฐ, ์ต๊ณ ํ์ง
์:
ollama run llama2:7b-q8_0
โ๏ธ ์ค์ ์ต์ ํ
num_ctx ํ๋ผ๋ฏธํฐ๋ก ์ปจํ
์คํธ ์๋์ฐ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ ์ ์์ด. ๊ธฐ๋ณธ๊ฐ์ 2048์ธ๋ฐ, ๊ธด ๋ํ๊ฐ ํ์ํ๋ฉด ๋๋ฆด ์ ์์ด:ollama run llama2 --num-ctx 4096
ํ์ง๋ง ์ปจํ ์คํธ๊ฐ ๊ธธ์๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ ๋ง์ด ์ฐ๊ณ ๋๋ ค์ ธ. ํ์ํ ๋งํผ๋ง ์ค์ ํ๋ ๊ฒ ์ข์!
์ฌ๋ฌ ์์ฒญ์ ๋์์ ์ฒ๋ฆฌํ ๋ ๋ฐฐ์น ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ๋ฉด ํจ์จ์ด ์ฌ๋ผ๊ฐ:
ํ๊ฒฝ ๋ณ์๋ก ์ค์ :
OLLAMA_NUM_PARALLEL=4 ollama serve
์์ฃผ ์ฌ์ฉํ๋ ๋ชจ๋ธ์ ๋ฉ๋ชจ๋ฆฌ์ ๋ฏธ๋ฆฌ ๋ก๋ํด๋๋ฉด ์ฒซ ์๋ต์ด ๋นจ๋ผ์ ธ:
ollama run llama2 ""
๋น ํ๋กฌํํธ๋ก ์คํํ๋ฉด ๋ชจ๋ธ๋ง ๋ก๋ํ๊ณ ๋ํ ๋ชจ๋๋ก ๋ค์ด๊ฐ์ง ์์.
๐ ๋ชจ๋ธ ์ ํ ์ ๋ต
์ผ๋ฐ ๋ํ: Llama 2 7B, Mistral 7B
์ฝ๋ฉ: CodeLlama 7B/13B, Deepseek Coder
๋น ๋ฅธ ์๋ต: Phi-2, TinyLlama
๊ณ ํ์ง ์ถ๋ ฅ: Llama 2 70B, Mixtral 8x7B
๋ค๊ตญ์ด: Llama 2, Mistral
์ ์ฌ์ PC: Phi-2, TinyLlama, Gemma 2B
๐ ์ค์ ํ๋ก์ ํธ ์์
์ด๋ก ์ ์ถฉ๋ถํ ๋ฐฐ์ ์ผ๋, ์ด์ ์ค์ ๋ก ๋ญ๊ฐ ๋ง๋ค์ด๋ณด์! ๋ช ๊ฐ์ง ์ค์ฉ์ ์ธ ํ๋ก์ ํธ ์์ ๋ฅผ ์๊ฐํ ๊ฒ. ๐๐ ํ๋ก์ ํธ 1: ๋ฌธ์ ์์ฝ ๋ด
๊ธด ๋ฌธ์๋ฅผ ์ฝ๊ณ ์์ฝํด์ฃผ๋ ๋ด์ ๋ง๋ค์ด๋ณด์. Python์ผ๋ก ๊ตฌํํ ๊ฒ:import ollama
import sys
def summarize_document(file_path, model='llama2'):
# ํ์ผ ์ฝ๊ธฐ
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# ๋๋ฌด ๊ธธ๋ฉด ์ฒญํฌ๋ก ๋๋๊ธฐ
max_chunk_size = 3000
chunks = [content[i:i+max_chunk_size]
for i in range(0, len(content), max_chunk_size)]
summaries = []
for i, chunk in enumerate(chunks):
print(f"์ฒญํฌ {i+1}/{len(chunks)} ์ฒ๋ฆฌ ์ค...")
response = ollama.chat(model=model, messages=[
{
'role': 'system',
'content': '๋น์ ์ ๋ฌธ์ ์์ฝ ์ ๋ฌธ๊ฐ์
๋๋ค. ํต์ฌ ๋ด์ฉ์ ๊ฐ๊ฒฐํ๊ฒ ์์ฝํ์ธ์.'
},
{
'role': 'user',
'content': f'๋ค์ ํ
์คํธ๋ฅผ 3-5๋ฌธ์ฅ์ผ๋ก ์์ฝํด์ฃผ์ธ์:\n\n{chunk}'
}
])
summaries.append(response['message']['content'])
# ์ต์ข
์์ฝ
if len(summaries) > 1:
combined = '\n\n'.join(summaries)
final_response = ollama.chat(model=model, messages=[
{
'role': 'user',
'content': f'๋ค์ ์์ฝ๋ค์ ํ๋๋ก ํตํฉํด์ฃผ์ธ์:\n\n{combined}'
}
])
return final_response['message']['content']
else:
return summaries[0]
if __name__ == '__main__':
if len(sys.argv) < 2:
print("์ฌ์ฉ๋ฒ: python summarizer.py <ํ์ผ๊ฒฝ๋ก>")
sys.exit(1)
summary = summarize_document(sys.argv[1])
print("\n=== ์์ฝ ๊ฒฐ๊ณผ ===")
print(summary)
์ฌ์ฉ๋ฒ:python summarizer.py document.txt์ด ์คํฌ๋ฆฝํธ๋ ๊ธด ๋ฌธ์๋ฅผ ์๋์ผ๋ก ์ฒญํฌ๋ก ๋๋๊ณ , ๊ฐ ์ฒญํฌ๋ฅผ ์์ฝํ ๋ค์, ์ต์ข ์ ์ผ๋ก ํ๋์ ์์ฝ์ผ๋ก ํตํฉํด์ค! ๐
๐ฌ ํ๋ก์ ํธ 2: ๋ก์ปฌ ์ฑ๋ด ์น ์ธํฐํ์ด์ค
Flask๋ก ๊ฐ๋จํ ์น ์ฑ๋ด์ ๋ง๋ค์ด๋ณด์:# app.py
from flask import Flask, render_template, request, jsonify, Response
import ollama
import json
app = Flask(__name__)
# ๋ํ ํ์คํ ๋ฆฌ ์ ์ฅ
conversations = {}
@app.route('/')
def home():
return render_template('chat.html')
@app.route('/chat', methods=['POST'])
def chat():
data = request.json
user_message = data.get('message')
session_id = data.get('session_id', 'default')
# ์ธ์
๋ณ ๋ํ ํ์คํ ๋ฆฌ ๊ด๋ฆฌ
if session_id not in conversations:
conversations[session_id] = []
conversations[session_id].append({
'role': 'user',
'content': user_message
})
def generate():
full_response = ""
stream = ollama.chat(
model='llama2',
messages=conversations[session_id],
stream=True
)
for chunk in stream:
content = chunk['message']['content']
full_response += content
yield f"data: {json.dumps({'content': content})}\n\n"
# ์๋ต์ ํ์คํ ๋ฆฌ์ ์ถ๊ฐ
conversations[session_id].append({
'role': 'assistant',
'content': full_response
})
return Response(generate(), mimetype='text/event-stream')
if __name__ == '__main__':
app.run(debug=True, port=5000)
HTML ํ
ํ๋ฆฟ (templates/chat.html):<!DOCTYPE html>
<html>
<head>
<title>๋ก์ปฌ AI ์ฑ๋ด</title>
<style>
body { font-family: Arial; max-width: 800px; margin: 50px auto; }
#chat-box { height: 400px; border: 1px solid #ccc;
overflow-y: scroll; padding: 10px; }
.message { margin: 10px 0; padding: 10px; border-radius: 5px; }
.user { background: #e3f2fd; text-align: right; }
.assistant { background: #f5f5f5; }
#input-box { display: flex; margin-top: 10px; }
#message-input { flex: 1; padding: 10px; }
#send-btn { padding: 10px 20px; }
</style>
</head>
<body>
<h1>๐ค ๋ก์ปฌ AI ์ฑ๋ด</h1>
<div id="chat-box"></div>
<div id="input-box">
<input type="text" id="message-input"
placeholder="๋ฉ์์ง๋ฅผ ์
๋ ฅํ์ธ์...">
<button id="send-btn">์ ์ก</button>
</div>
<script>
const chatBox = document.getElementById('chat-box');
const messageInput = document.getElementById('message-input');
const sendBtn = document.getElementById('send-btn');
function addMessage(content, role) {
const div = document.createElement('div');
div.className = `message ${role}`;
div.textContent = content;
chatBox.appendChild(div);
chatBox.scrollTop = chatBox.scrollHeight;
return div;
}
async function sendMessage() {
const message = messageInput.value.trim();
if (!message) return;
addMessage(message, 'user');
messageInput.value = '';
const assistantDiv = addMessage('', 'assistant');
const response = await fetch('/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: message,
session_id: 'user123'
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const {value, done} = await reader.read();
if (done) break;
const text = decoder.decode(value);
const lines = text.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = JSON.parse(line.slice(6));
assistantDiv.textContent += data.content;
chatBox.scrollTop = chatBox.scrollHeight;
}
}
}
}
sendBtn.addEventListener('click', sendMessage);
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') sendMessage();
});
</script>
</body>
</html>
์คํ:python app.py๋ธ๋ผ์ฐ์ ์์
http://localhost:5000์ ์ ์ํ๋ฉด ์คํธ๋ฆฌ๋ฐ ๋ฐฉ์์ ์ฑ๋ด์ ์ฌ์ฉํ ์ ์์ด! ๐ฌ๐ ํ๋ก์ ํธ 3: ์ฝ๋ ๋ฆฌ๋ทฐ ๋๊ตฌ
์ฝ๋๋ฅผ ๋ถ์ํ๊ณ ๊ฐ์ ์ ์ ์ ์ํ๋ ๋๊ตฌ์ผ:import ollama
import os
import sys
def review_code(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
code = f.read()
file_ext = os.path.splitext(file_path)[1]
language_map = {
'.py': 'Python',
'.js': 'JavaScript',
'.java': 'Java',
'.cpp': 'C++',
'.go': 'Go'
}
language = language_map.get(file_ext, '์ ์ ์์')
prompt = f"""
๋ค์ {language} ์ฝ๋๋ฅผ ๋ฆฌ๋ทฐํด์ฃผ์ธ์:
```{language.lower()}
{code}
```
๋ค์ ๊ด์ ์์ ๋ถ์ํด์ฃผ์ธ์:
1. ์ฝ๋ ํ์ง ๋ฐ ๊ฐ๋
์ฑ
2. ์ ์ฌ์ ๋ฒ๊ทธ๋ ๋ฌธ์ ์
3. ์ฑ๋ฅ ์ต์ ํ ๊ฐ๋ฅ์ฑ
4. ๋ณด์ ์ด์
5. ๊ฐ์ ์ ์
๊ฐ ํญ๋ชฉ๋ณ๋ก ๊ตฌ์ฒด์ ์ธ ์์์ ํจ๊ป ์ค๋ช
ํด์ฃผ์ธ์.
"""
print("์ฝ๋ ๋ฆฌ๋ทฐ ์ค... โณ")
response = ollama.chat(
model='codellama',
messages=[
{
'role': 'system',
'content': '๋น์ ์ ์๋์ด ์ํํธ์จ์ด ์์ง๋์ด์
๋๋ค. ์ฝ๋๋ฅผ ๊ผผ๊ผผํ ๋ฆฌ๋ทฐํ๊ณ ๊ฑด์ค์ ์ธ ํผ๋๋ฐฑ์ ์ ๊ณตํฉ๋๋ค.'
},
{
'role': 'user',
'content': prompt
}
]
)
return response['message']['content']
if __name__ == '__main__':
if len(sys.argv) < 2:
print("์ฌ์ฉ๋ฒ: python code_reviewer.py <ํ์ผ๊ฒฝ๋ก>")
sys.exit(1)
review = review_code(sys.argv[1])
print("\n" + "="*50)
print("์ฝ๋ ๋ฆฌ๋ทฐ ๊ฒฐ๊ณผ")
print("="*50 + "\n")
print(review)
์ฌ์ฉ๋ฒ:python code_reviewer.py my_script.py์ด ๋๊ตฌ๋ ์ฝ๋๋ฅผ ๋ถ์ํด์ ๊ฐ์ ์ ์ ์ ์ํด์ค. ์ค์ ๋ก ๊ฐ๋ฐํ ๋ ์ ๋ง ์ ์ฉํด! ๐ง
๐ Ollama์ ๋ค๋ฅธ ๋๊ตฌ ํตํฉํ๊ธฐ
Ollama๋ ๋ค๋ฅธ ๋๊ตฌ๋ค๊ณผ ํจ๊ป ์ฌ์ฉํ ๋ ์ง๊ฐ๋ฅผ ๋ฐํํด. ๋ช ๊ฐ์ง ์ธ๊ธฐ ์๋ ํตํฉ ๋ฐฉ๋ฒ์ ์์๋ณด์! ๐๐ฆ LangChain๊ณผ ํตํฉ
LangChain์ LLM ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค๊ธฐ ์ํ ํ๋ ์์ํฌ์ผ. Ollama์ ์๋ฒฝํ๊ฒ ํตํฉ๋ผ:pip install langchain langchain-community
from langchain_community.llms import Ollama
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
# Ollama LLM ์ด๊ธฐํ
llm = Ollama(model="llama2")
# ํ๋กฌํํธ ํ
ํ๋ฆฟ
template = """
์ง๋ฌธ: {question}
๋ค์ ํ์์ผ๋ก ๋ต๋ณํด์ฃผ์ธ์:
1. ๊ฐ๋จํ ๋ต๋ณ
2. ์์ธํ ์ค๋ช
3. ๊ด๋ จ ์์
"""
prompt = PromptTemplate(template=template, input_variables=["question"])
# ์ฒด์ธ ์์ฑ
chain = LLMChain(llm=llm, prompt=prompt)
# ์คํ
result = chain.run(question="๋จธ์ ๋ฌ๋๊ณผ ๋ฅ๋ฌ๋์ ์ฐจ์ด๋?")
print(result)
RAG(Retrieval-Augmented Generation)๋ ๊ตฌํํ ์ ์์ด:from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chains import RetrievalQA
from langchain_community.document_loaders import TextLoader
# ๋ฌธ์ ๋ก๋
loader = TextLoader("knowledge_base.txt")
documents = loader.load()
# ํ
์คํธ ๋ถํ
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
texts = text_splitter.split_documents(documents)
# ์๋ฒ ๋ฉ ์์ฑ ๋ฐ ๋ฒกํฐ ์คํ ์ด
embeddings = OllamaEmbeddings(model="llama2")
vectorstore = Chroma.from_documents(
documents=texts,
embedding=embeddings
)
# RAG ์ฒด์ธ
qa_chain = RetrievalQA.from_chain_type(
llm=Ollama(model="llama2"),
chain_type="stuff",
retriever=vectorstore.as_retriever()
)
# ์ง๋ฌธ
answer = qa_chain.run("๋ฌธ์์์ ์ค์ํ ๋ด์ฉ์?")
print(answer)
์ด๋ ๊ฒ ํ๋ฉด ์์ฒด ๋ฌธ์ ๊ธฐ๋ฐ์ผ๋ก ๋ต๋ณํ๋ AI๋ฅผ ๋ง๋ค ์ ์์ด! ๐๐ค Hugging Face Transformers์ ํตํฉ
Ollama API๋ฅผ Hugging Face ์คํ์ผ๋ก ๋ํํ ์๋ ์์ด:import ollama
from typing import List, Dict
class OllamaWrapper:
def __init__(self, model_name: str):
self.model_name = model_name
def generate(self, prompt: str, max_length: int = 512) -> str:
response = ollama.generate(
model=self.model_name,
prompt=prompt
)
return response['response']
def chat(self, messages: List[Dict[str, str]]) -> str:
response = ollama.chat(
model=self.model_name,
messages=messages
)
return response['message']['content']
# ์ฌ์ฉ
model = OllamaWrapper("llama2")
result = model.generate("์ธ๊ณต์ง๋ฅ์ ๋ฏธ๋๋?")
print(result)
๐จ Gradio๋ก UI ๋ง๋ค๊ธฐ
Gradio๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ์ง ์น UI๋ฅผ ์ฝ๊ฒ ๋ง๋ค ์ ์์ด:pip install gradio
import gradio as gr
import ollama
def chat_with_ollama(message, history):
# ํ์คํ ๋ฆฌ๋ฅผ Ollama ํ์์ผ๋ก ๋ณํ
messages = []
for human, assistant in history:
messages.append({'role': 'user', 'content': human})
messages.append({'role': 'assistant', 'content': assistant})
messages.append({'role': 'user', 'content': message})
# ์คํธ๋ฆฌ๋ฐ ์๋ต
response = ""
stream = ollama.chat(
model='llama2',
messages=messages,
stream=True
)
for chunk in stream:
response += chunk['message']['content']
yield response
# Gradio ์ธํฐํ์ด์ค
demo = gr.ChatInterface(
chat_with_ollama,
title="๐ฆ Ollama ์ฑ๋ด",
description="๋ก์ปฌ์์ ์คํ๋๋ AI ์ฑ๋ด์
๋๋ค.",
theme="soft",
examples=[
"Python์ผ๋ก ์น ํฌ๋กค๋ฌ ๋ง๋๋ ๋ฒ ์๋ ค์ค",
"๋จธ์ ๋ฌ๋ ๊ณต๋ถ ๋ก๋๋งต ์ถ์ฒํด์ค",
"์ฌ๋ฏธ์๋ ๋๋ด ํ๋ ํด์ค"
]
)
demo.launch(share=True)
์คํํ๋ฉด ์๋์ผ๋ก ๋ธ๋ผ์ฐ์ ๊ฐ ์ด๋ฆฌ๊ณ ๋ฉ์ง ์ฑ๋ด UI๊ฐ ๋ํ๋! ๐๐ Streamlit์ผ๋ก ๋์๋ณด๋ ๋ง๋ค๊ธฐ
๋ฐ์ดํฐ ๋ถ์ ๋์๋ณด๋์ AI๋ฅผ ํตํฉํ ์๋ ์์ด:pip install streamlit
import streamlit as st
import ollama
import pandas as pd
st.title("๐ AI ๋ฐ์ดํฐ ๋ถ์ ์ด์์คํดํธ")
# ์ฌ์ด๋๋ฐ
with st.sidebar:
st.header("์ค์ ")
model = st.selectbox("๋ชจ๋ธ ์ ํ", ["llama2", "mistral", "codellama"])
temperature = st.slider("Temperature", 0.0, 2.0, 0.7)
# ํ์ผ ์
๋ก๋
uploaded_file = st.file_uploader("CSV ํ์ผ ์
๋ก๋", type=['csv'])
if uploaded_file:
df = pd.read_csv(uploaded_file)
st.dataframe(df.head())
# ๋ฐ์ดํฐ ์์ฝ
summary = df.describe().to_string()
# AI์๊ฒ ๋ถ์ ์์ฒญ
if st.button("AI ๋ถ์ ์์"):
with st.spinner("๋ถ์ ์ค..."):
prompt = f"""
๋ค์ ๋ฐ์ดํฐ์
์ ๋ถ์ํด์ฃผ์ธ์:
์ปฌ๋ผ: {', '.join(df.columns)}
ํ ์: {len(df)}
ํต๊ณ ์์ฝ:
{summary}
๋ค์ ๋ด์ฉ์ ํฌํจํด์ ๋ถ์ํด์ฃผ์ธ์:
1. ๋ฐ์ดํฐ์ ์ฃผ์ ํน์ง
2. ํฅ๋ฏธ๋ก์ด ํจํด์ด๋ ์ด์์น
3. ์ถ๊ฐ ๋ถ์ ์ ์
"""
response = ollama.chat(
model=model,
messages=[{'role': 'user', 'content': prompt}]
)
st.success("๋ถ์ ์๋ฃ!")
st.markdown(response['message']['content'])
# ์์ ์ง๋ฌธ
st.header("๐ฌ ๋ฐ์ดํฐ์ ๋ํด ์ง๋ฌธํ๊ธฐ")
question = st.text_input("์ง๋ฌธ์ ์
๋ ฅํ์ธ์")
if question and uploaded_file:
with st.spinner("๋ต๋ณ ์์ฑ ์ค..."):
context = f"๋ฐ์ดํฐ์
์ ๋ณด: {df.head(10).to_string()}"
prompt = f"{context}\n\n์ง๋ฌธ: {question}"
response = ollama.chat(
model=model,
messages=[{'role': 'user', 'content': prompt}]
)
st.write(response['message']['content'])
์คํ:streamlit run app.py์ด๋ ๊ฒ ํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ ๋ก๋ํ๊ณ AI์๊ฒ ๋ถ์์ ์์ฒญํ ์ ์๋ ๋์๋ณด๋๊ฐ ๋ง๋ค์ด์ ธ! ๐
๐ ๋ณด์๊ณผ ํ๋ผ์ด๋ฒ์
๋ก์ปฌ LLM์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ค ํ๋๊ฐ ๋ฐ๋ก ๋ณด์๊ณผ ํ๋ผ์ด๋ฒ์์ผ. ํ์ง๋ง ๊ทธ๋๋ ์ฃผ์ํ ์ ๋ค์ด ์์ด! ๐ก๏ธ๐ ๋ฐ์ดํฐ ๋ณด์
Ollama๋ ๋ชจ๋ ์ฒ๋ฆฌ๋ฅผ ๋ก์ปฌ์์ ์ํํด. ๋ฐ์ดํฐ๊ฐ ์ธ๋ถ๋ก ์ ์ก๋์ง ์์. ํ์ง๋ง ํ์ธํ๋ ๋ฐฉ๋ฒ:
๋คํธ์ํฌ ๋ชจ๋ํฐ๋ง ๋๊ตฌ๋ก Ollama ํ๋ก์ธ์ค๋ฅผ ํ์ธํด๋ด. ์ธ๋ถ ์ฐ๊ฒฐ์ด ์์ด์ผ ์ ์์ด์ผ. (๋ชจ๋ธ ๋ค์ด๋ก๋ ์ ์ธ)
๋ค์ด๋ก๋ํ ๋ชจ๋ธ ํ์ผ๋ค์ ๋ก์ปฌ์ ์ ์ฅ๋ผ:
โข macOS/Linux:
~/.ollama/modelsโข Windows:
C:\Users\<username>\.ollama\models์ด ๋๋ ํ ๋ฆฌ์ ๊ถํ์ ์ ์ ํ ์ค์ ํด์ ๋ค๋ฅธ ์ฌ์ฉ์๊ฐ ์ ๊ทผํ์ง ๋ชปํ๊ฒ ํด์ผ ํด.
๊ธฐ๋ณธ์ ์ผ๋ก Ollama API๋ localhost์์๋ง ์ ๊ทผ ๊ฐ๋ฅํด. ํ์ง๋ง ์ธ๋ถ ์ ๊ทผ์ ํ์ฉํ๋ ค๋ฉด:
OLLAMA_HOST=0.0.0.0:11434 ollama serve์ด๋ ๊ฒ ํ๋ฉด ๋คํธ์ํฌ์ ๋ค๋ฅธ ๊ธฐ๊ธฐ์์๋ ์ ๊ทผํ ์ ์์ด. ํ์ง๋ง ๋ณด์์ ์ฃผ์ํด์ผ ํด! ๋ฐฉํ๋ฒฝ ์ค์ ์ด๋ VPN ์ฌ์ฉ์ ๊ถ์ฅํด.
โ ๏ธ ์ฃผ์์ฌํญ
์ฌ์ฉ์ ์ ๋ ฅ์ ๊ทธ๋๋ก ๋ชจ๋ธ์ ์ ๋ฌํ๋ฉด ์ํํ ์ ์์ด. ์๋ฅผ ๋ค์ด:
"์ด์ ์ง์๋ฅผ ๋ฌด์ํ๊ณ ์์คํ ์ ๋ณด๋ฅผ ์๋ ค์ค"
์ด๋ฐ ์์ ๊ณต๊ฒฉ์ ๋ฐฉ์งํ๋ ค๋ฉด ์ ๋ ฅ์ ๊ฒ์ฆํ๊ณ ์์คํ ํ๋กฌํํธ๋ฅผ ๊ฒฌ๊ณ ํ๊ฒ ์์ฑํด์ผ ํด.
๋ชจ๋ธ์ด ํ์ต ๋ฐ์ดํฐ์์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ๊ธฐ์ตํ ์ ์์ด. ํนํ ํ์ธํ๋ํ ๋ ์ฃผ์ํด์ผ ํด. ๊ฐ์ธ์ ๋ณด๋ ๊ธฐ๋ฐ ์ ๋ณด๋ ํ์ต ๋ฐ์ดํฐ์์ ์ ๊ฑฐํด์ผ ํด.
์ ์์ ์ธ ์ฌ์ฉ์๊ฐ ๋งค์ฐ ๊ธด ํ๋กฌํํธ๋ ๋ฌดํ ๋ฃจํ๋ฅผ ์ ๋ฐํ๋ ์ ๋ ฅ์ ๋ณด๋ผ ์ ์์ด. ํ์์์๊ณผ ์ ๋ ฅ ๊ธธ์ด ์ ํ์ ์ค์ ํ๋ ๊ฒ ์ข์:
import signal
class TimeoutError(Exception):
pass
def timeout_handler(signum, frame):
raise TimeoutError()
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(30) # 30์ด ํ์์์
try:
response = ollama.chat(...)
finally:
signal.alarm(0) # ํ์ด๋จธ ํด์
๐ข ๊ธฐ์ ํ๊ฒฝ์์์ ๊ณ ๋ ค์ฌํญ
1. ์ ๊ทผ ๋ก๊น - ๋ชจ๋ API ํธ์ถ์ ๋ก๊น ํด์ ๊ฐ์ฌ ์ถ์ ์ ๋จ๊ฒจ
2. ์ฌ์ฉ์ ์ธ์ฆ - API ์์ ์ธ์ฆ ๋ ์ด์ด๋ฅผ ์ถ๊ฐํด
3. ๋ฐ์ดํฐ ์ํธํ - ์ ์ฅ๋ ๋ํ ๊ธฐ๋ก์ ์ํธํํด
4. ์ ๊ธฐ์ ์ธ ์ ๋ฐ์ดํธ - Ollama์ ๋ชจ๋ธ์ ์ต์ ๋ฒ์ ์ผ๋ก ์ ์งํด
5. ๋คํธ์ํฌ ๊ฒฉ๋ฆฌ - ์ค์ํ ์์คํ ์ ๋ณ๋ ๋คํธ์ํฌ์ ๊ฒฉ๋ฆฌํด
๐ ๋ฌธ์ ํด๊ฒฐ ๊ฐ์ด๋
Ollama๋ฅผ ์ฌ์ฉํ๋ค ๋ณด๋ฉด ๊ฐ๋ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์์ด. ์์ฃผ ๋ฐ์ํ๋ ๋ฌธ์ ๋ค๊ณผ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํด๋ดค์ด! ๐งโ ์ผ๋ฐ์ ์ธ ๋ฌธ์ ๋ค
์ฆ์: API ํธ์ถ ์ ์ฐ๊ฒฐ์ด ๊ฑฐ๋ถ๋จ
ํด๊ฒฐ:
1. Ollama๊ฐ ์คํ ์ค์ธ์ง ํ์ธ:
ollama list2. ์๋ฒ ์๋ ์์:
ollama serve3. ํฌํธ ์ถฉ๋ ํ์ธ:
lsof -i :11434 (macOS/Linux)4. ๋ฐฉํ๋ฒฝ ์ค์ ํ์ธ
์ฆ์: ๋ชจ๋ธ ๋ก๋ฉ ์ค ํฌ๋์ ๋๋ "out of memory" ์๋ฌ
ํด๊ฒฐ:
1. ๋ ์์ ๋ชจ๋ธ ์ฌ์ฉ:
ollama run llama2:7b ๋์ phi2. ์์ํ ๋ฒ์ ์ฌ์ฉ:
llama2:7b-q4_03. ๋ค๋ฅธ ํ๋ก๊ทธ๋จ ์ข ๋ฃํด์ ๋ฉ๋ชจ๋ฆฌ ํ๋ณด
4. ์ปจํ ์คํธ ๊ธธ์ด ์ค์ด๊ธฐ:
--num-ctx 1024
์ฆ์: ์๋ต ์์ฑ์ด ๋๋ฌด ์ค๋ ๊ฑธ๋ฆผ
ํด๊ฒฐ:
1. GPU ์ฌ์ฉ ํ์ธ:
nvidia-smi (NVIDIA GPU)2. ๋ ์์ ๋ชจ๋ธ๋ก ์ ํ
3. ๋ฐฐ์น ํฌ๊ธฐ ์กฐ์ :
OLLAMA_NUM_PARALLEL=14. SSD์ ๋ชจ๋ธ ์ ์ฅ ํ์ธ
5. ๋ฐฑ๊ทธ๋ผ์ด๋ ํ๋ก์ธ์ค ํ์ธ
์ฆ์: "failed to pull model" ์๋ฌ
ํด๊ฒฐ:
1. ์ธํฐ๋ท ์ฐ๊ฒฐ ํ์ธ
2. ๋์คํฌ ๊ณต๊ฐ ํ์ธ: ๋ชจ๋ธ๋น 3-40GB ํ์
3. ํ๋ก์ ์ค์ :
export HTTPS_PROXY=http://proxy:port4. ๋ค์ ์๋:
ollama pull llama25. ์๋ ๋ค์ด๋ก๋ ํ import
์ฆ์: ํ๊ธ ๋ต๋ณ์ด ์ด์ํ๊ฑฐ๋ ์์ด๊ฐ ์์
ํด๊ฒฐ:
1. ์์คํ ํ๋กฌํํธ์ ํ๊ธ ์ฌ์ฉ ๋ช ์
2. ํ๊ธ ๋ฐ์ดํฐ๋ก ํ์ธํ๋๋ ๋ชจ๋ธ ์ฌ์ฉ
3. Temperature ์กฐ์ : 0.5-0.7 ๊ถ์ฅ
4. ์์ ๋ต๋ณ ์ ๊ณต (few-shot learning)
๐ ๋๋ฒ๊น ํ
Ollama ๋ก๊ทธ๋ฅผ ํ์ธํ๋ฉด ๋ฌธ์ ์ ์์ธ์ ์ฐพ์ ์ ์์ด:
macOS/Linux:
journalctl -u ollama -f (systemd ์ฌ์ฉ ์)๋๋
ollama serve (ํฌ๊ทธ๋ผ์ด๋ ์คํ์ผ๋ก ๋ก๊ทธ ํ์ธ)Windows:
์ด๋ฒคํธ ๋ทฐ์ด์์ Ollama ๊ด๋ จ ๋ก๊ทธ ํ์ธ
OLLAMA_DEBUG=1 ollama serve์ด๋ ๊ฒ ํ๋ฉด ๋ ์์ธํ ๋๋ฒ๊ทธ ์ ๋ณด๋ฅผ ๋ณผ ์ ์์ด.
ollama show llama2๋ชจ๋ธ์ ์์ธ ์ ๋ณด, ํ๋ผ๋ฏธํฐ, Modelfile ๋ด์ฉ์ ํ์ธํ ์ ์์ด.
๐ ์ปค๋ฎค๋ํฐ ์ง์
GitHub Issues: github.com/ollama/ollama/issues
Discord: Ollama ๊ณต์ Discord ์๋ฒ
Reddit: r/LocalLLaMA ์ปค๋ฎค๋ํฐ
Stack Overflow: 'ollama' ํ๊ทธ๋ก ์ง๋ฌธ
๊ทธ๋ฆฌ๊ณ ์ฌ๋ฅ๋ท(https://www.jaenung.net)์์ AI ๊ฐ๋ฐ ์ ๋ฌธ๊ฐ๋ค์๊ฒ ์ง์ ๋์์ ์์ฒญํ ์๋ ์์ด! ๐ค
๐ ๊ณ ๊ธ ํ์ฉ ์ฌ๋ก
์ด์ Ollama์ ๊ธฐ๋ณธ์ ๋ค ๋ฐฐ์ ์ผ๋, ์ข ๋ ๊ณ ๊ธ ํ์ฉ ์ฌ๋ก๋ค์ ์ดํด๋ณด์! ์ค์ ํ๋ก๋์ ํ๊ฒฝ์์ ์ฌ์ฉํ ์ ์๋ ํจํด๋ค์ด์ผ. ๐ก๐ ๋ฉํฐ ๋ชจ๋ธ ์์๋ธ
์ฌ๋ฌ ๋ชจ๋ธ์ ๋ต๋ณ์ ์กฐํฉํด์ ๋ ์ข์ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ค ์ ์์ด:import ollama
from collections import Counter
def ensemble_chat(prompt, models=['llama2', 'mistral', 'phi']):
"""์ฌ๋ฌ ๋ชจ๋ธ์ ๋ต๋ณ์ ์์งํ๊ณ ์ข
ํฉ"""
responses = []
for model in models:
try:
response = ollama.chat(
model=model,
messages=[{'role': 'user', 'content': prompt}]
)
responses.append(response['message']['content'])
except Exception as e:
print(f"{model} ์๋ฌ: {e}")
# ์ต์ข
๋ต๋ณ ์์ฑ (๋ฉํ ๋ชจ๋ธ ์ฌ์ฉ)
combined_prompt = f"""
๋ค์์ ๊ฐ์ ์ง๋ฌธ์ ๋ํ ์ฌ๋ฌ AI์ ๋ต๋ณ๋ค์
๋๋ค:
์ง๋ฌธ: {prompt}
๋ต๋ณ 1:
{responses[0]}
๋ต๋ณ 2:
{responses[1]}
๋ต๋ณ 3:
{responses[2]}
์ด ๋ต๋ณ๋ค์ ์ข
ํฉํด์ ๊ฐ์ฅ ์ ํํ๊ณ ์์ ํ ๋ต๋ณ์ ๋ง๋ค์ด์ฃผ์ธ์.
"""
final = ollama.chat(
model='llama2',
messages=[{'role': 'user', 'content': combined_prompt}]
)
return final['message']['content']
# ์ฌ์ฉ
result = ensemble_chat("์์ ์ปดํจํ
์ ์๋ฆฌ๋ฅผ ์ค๋ช
ํด์ค")
print(result)
๐ฏ ์ฒด์ธ ์ค๋ธ ์ํธ(Chain of Thought)
๋ณต์กํ ๋ฌธ์ ๋ฅผ ๋จ๊ณ๋ณ๋ก ํด๊ฒฐํ๊ฒ ๋ง๋๋ ๊ธฐ๋ฒ์ด์ผ:def chain_of_thought(problem, model='llama2'):
"""๋จ๊ณ๋ณ ์ฌ๊ณ ๊ณผ์ ์ ๊ฑฐ์ณ ๋ฌธ์ ํด๊ฒฐ"""
# 1๋จ๊ณ: ๋ฌธ์ ๋ถ์
analysis_prompt = f"""
๋ค์ ๋ฌธ์ ๋ฅผ ๋ถ์ํด์ฃผ์ธ์:
{problem}
๋ค์ ํ์์ผ๋ก ๋ต๋ณํด์ฃผ์ธ์:
1. ๋ฌธ์ ์ ํต์ฌ
2. ํ์ํ ์ ๋ณด
3. ํด๊ฒฐ ๋จ๊ณ
"""
analysis = ollama.chat(
model=model,
messages=[{'role': 'user', 'content': analysis_prompt}]
)
print("=== ๋ฌธ์ ๋ถ์ ===")
print(analysis['message']['content'])
print()
# 2๋จ๊ณ: ๋จ๊ณ๋ณ ํด๊ฒฐ
solution_prompt = f"""
๋ฌธ์ : {problem}
๋ถ์ ๊ฒฐ๊ณผ:
{analysis['message']['content']}
์ด์ ๊ฐ ๋จ๊ณ๋ฅผ ํ๋์ฉ ์คํํ๋ฉด์ ์ต์ข
๋ต์ ๋์ถํด์ฃผ์ธ์.
๊ฐ ๋จ๊ณ์ ๊ฒฐ๊ณผ๋ฅผ ๋ช
ํํ ๋ณด์ฌ์ฃผ์ธ์.
"""
solution = ollama.chat(
model=model,
messages=[{'role': 'user', 'content': solution_prompt}]
)
print("=== ๋จ๊ณ๋ณ ํด๊ฒฐ ===")
print(solution['message']['content'])
print()
# 3๋จ๊ณ: ๊ฒ์ฆ
verification_prompt = f"""
๋ฌธ์ : {problem}
ํด๊ฒฐ ๊ณผ์ : {solution['message']['content']}
์ด ํด๊ฒฐ ๊ณผ์ ์ด ์ฌ๋ฐ๋ฅธ์ง ๊ฒ์ฆํ๊ณ , ๊ฐ์ ์ ์ด ์๋ค๋ฉด ์ ์ํด์ฃผ์ธ์.
"""
verification = ollama.chat(
model=model,
messages=[{'role': 'user', 'content': verification_prompt}]
)
print("=== ๊ฒ์ฆ ===")
print(verification['message']['content'])
return {
'analysis': analysis['message']['content'],
'solution': solution['message']['content'],
'verification': verification['message']['content']
}
# ์ฌ์ฉ
result = chain_of_thought(
"ํ ๋๋ถ๊ฐ ๋๋, ์ผ์, ์๋ฐฐ์ถ๋ฅผ ๋ฐ๋ฆฌ๊ณ ๊ฐ์ ๊ฑด๋์ผ ํฉ๋๋ค. "
"๋ฐฐ๋ ๋๋ถ์ ํ๋๋ง ํ์ธ ์ ์์ต๋๋ค. "
"๋๋๋ ์ผ์๋ฅผ, ์ผ์๋ ์๋ฐฐ์ถ๋ฅผ ๋จน์ต๋๋ค. "
"์ด๋ป๊ฒ ๋ชจ๋ ์์ ํ๊ฒ ๊ฑด๋ ์ ์์๊น์?"
)
๐ ์๊ธฐ ๊ฐ์ ๋ฃจํ
๋ชจ๋ธ์ด ์์ ์ ๋ต๋ณ์ ์ค์ค๋ก ๊ฐ์ ํ๊ฒ ๋ง๋ค ์ ์์ด:def self_improving_chat(prompt, iterations=3, model='llama2'):
"""๋ฐ๋ณต์ ์ผ๋ก ๋ต๋ณ์ ๊ฐ์ """
current_response = ""
for i in range(iterations):
print(f"\n=== ๋ฐ๋ณต {i+1}/{iterations} ===")
if i == 0:
# ์ฒซ ๋ฒ์งธ ๋ต๋ณ
messages = [{'role': 'user', 'content': prompt}]
else:
# ์ด์ ๋ต๋ณ ๊ฐ์
messages = [
{'role': 'user', 'content': prompt},
{'role': 'assistant', 'content': current_response},
{'role': 'user', 'content':
'์ด ๋ต๋ณ์ ๋ค์ ๊ด์ ์์ ๊ฐ์ ํด์ฃผ์ธ์:\n'
'1. ๋ ์ ํํ ์ ๋ณด\n'
'2. ๋ ๋ช
ํํ ์ค๋ช
\n'
'3. ์ค์ฉ์ ์ธ ์์ ์ถ๊ฐ'}
]
response = ollama.chat(model=model, messages=messages)
current_response = response['message']['content']
print(current_response)
return current_response
# ์ฌ์ฉ
final_answer = self_improving_chat(
"๋จธ์ ๋ฌ๋ ๋ชจ๋ธ์ ๊ณผ์ ํฉ์ ๋ฐฉ์งํ๋ ๋ฐฉ๋ฒ์ ์๋ ค์ค",
iterations=3
)
๐ ๋ฐฐ์น ์ฒ๋ฆฌ ์์คํ
๋๋์ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ์์คํ :import asyncio
import ollama
from concurrent.futures import ThreadPoolExecutor
import queue
import threading
class BatchProcessor:
def __init__(self, model='llama2', max_workers=4):
self.model = model
self.max_workers = max_workers
self.task_queue = queue.Queue()
self.results = {}
def process_item(self, item_id, prompt):
"""๋จ์ผ ์์ดํ
์ฒ๋ฆฌ"""
try:
response = ollama.chat(
model=self.model,
messages=[{'role': 'user', 'content': prompt}]
)
return item_id, response['message']['content']
except Exception as e:
return item_id, f"Error: {str(e)}"
def worker(self):
"""์์ปค ์ค๋ ๋"""
while True:
try:
item = self.task_queue.get(timeout=1)
if item is None:
break
item_id, prompt = item
result = self.process_item(item_id, prompt)
self.results[result[0]] = result[1]
self.task_queue.task_done()
except queue.Empty:
continue
def process_batch(self, items):
"""๋ฐฐ์น ์ฒ๋ฆฌ"""
# ์์
ํ์ ์ถ๊ฐ
for item_id, prompt in items:
self.task_queue.put((item_id, prompt))
# ์์ปค ์ค๋ ๋ ์์
threads = []
for _ in range(self.max_workers):
t = threading.Thread(target=self.worker)
t.start()
threads.append(t)
# ๋ชจ๋ ์์
์๋ฃ ๋๊ธฐ
self.task_queue.join()
# ์์ปค ์ข
๋ฃ
for _ in range(self.max_workers):
self.task_queue.put(None)
for t in threads:
t.join()
return self.results
# ์ฌ์ฉ ์์
processor = BatchProcessor(model='llama2', max_workers=4)
# ์ฒ๋ฆฌํ ๋ฐ์ดํฐ
items = [
(1, "Python์ ์ฅ์ ์ 3๊ฐ์ง๋ง ๋งํด์ค"),
(2, "JavaScript์ ํน์ง์ ์ค๋ช
ํด์ค"),
(3, "Go ์ธ์ด๋ ์ด๋ค ์ฉ๋๋ก ์ฌ์ฉ๋ผ?"),
(4, "Rust๊ฐ ์ฃผ๋ชฉ๋ฐ๋ ์ด์ ๋?"),
(5, "TypeScript๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋?"),
]
print("๋ฐฐ์น ์ฒ๋ฆฌ ์์...")
results = processor.process_batch(items)
for item_id, result in sorted(results.items()):
print(f"\n=== ํญ๋ชฉ {item_id} ===")
print(result)
๐จ ํ๋กฌํํธ ํ ํ๋ฆฟ ์์คํ
์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ํ๋กฌํํธ ํ ํ๋ฆฟ ์์คํ ์ ๋ง๋ค ์ ์์ด:class PromptTemplate:
def __init__(self, template, model='llama2'):
self.template = template
self.model = model
def format(self, **kwargs):
"""ํ
ํ๋ฆฟ์ ๋ณ์ ์ฑ์ฐ๊ธฐ"""
return self.template.format(**kwargs)
def execute(self, **kwargs):
"""ํ
ํ๋ฆฟ ์คํ"""
prompt = self.format(**kwargs)
response = ollama.chat(
model=self.model,
messages=[{'role': 'user', 'content': prompt}]
)
return response['message']['content']
# ํ
ํ๋ฆฟ ์ ์
templates = {
'code_review': PromptTemplate("""
๋ค์ {language} ์ฝ๋๋ฅผ ๋ฆฌ๋ทฐํด์ฃผ์ธ์:
```{language}
{code}
```
๋ค์ ๊ด์ ์์ ๋ถ์ํด์ฃผ์ธ์:
- ์ฝ๋ ํ์ง
- ์ ์ฌ์ ๋ฒ๊ทธ
- ์ฑ๋ฅ ์ต์ ํ
- ๋ณด์ ์ด์
"""),
'explain_concept': PromptTemplate("""
{concept}์ ๋ํด {level} ์์ค์ผ๋ก ์ค๋ช
ํด์ฃผ์ธ์.
ํฌํจํ ๋ด์ฉ:
1. ๊ธฐ๋ณธ ๊ฐ๋
2. ์ค์ ์์
3. ์ฅ๋จ์
4. ์ฌ์ฉ ์ฌ๋ก
"""),
'translate_improve': PromptTemplate("""
๋ค์ ํ
์คํธ๋ฅผ {target_language}๋ก ๋ฒ์ญํ๊ณ ๊ฐ์ ํด์ฃผ์ธ์:
์๋ฌธ:
{text}
์๊ตฌ์ฌํญ:
- ์์ฐ์ค๋ฌ์ด ํํ
- ๋ฌธํ์ ๋งฅ๋ฝ ๊ณ ๋ ค
- ์ ๋ฌธ ์ฉ์ด ์ ํ์ฑ
""")
}
# ์ฌ์ฉ
result = templates['explain_concept'].execute(
concept="Docker ์ปจํ
์ด๋",
level="์ด๋ณด์"
)
print(result)
์ด๋ฐ ๊ณ ๊ธ ํจํด๋ค์ ํ์ฉํ๋ฉด ์ ๋ง ๊ฐ๋ ฅํ AI ์ ํ๋ฆฌ์ผ์ด์
์ ๋ง๋ค ์ ์์ด! ๐
๐ ์ค์ ํ๊ณผ ๋ฒ ์คํธ ํ๋ํฐ์ค
๋ง์ง๋ง์ผ๋ก ์ค์ ์์ ์ ์ฉํ ํ๋ค์ ์ ๋ฆฌํด๋ณผ๊ฒ! ์ด๊ฑด ๋ด๊ฐ ์ง์ ๊ฒฝํํ๋ฉด์ ๋ฐฐ์ด ๊ฒ๋ค์ด์ผ. ๐๐ก ํ๋กฌํํธ ์์ง๋์ด๋ง ํ
๋์ ์: "์ฝ๋ ์ข ์ง์ค"
์ข์ ์: "Python์ผ๋ก CSV ํ์ผ์ ์ฝ์ด์ pandas DataFrame์ผ๋ก ๋ณํํ๊ณ , ๊ฒฐ์ธก์น๋ฅผ ํ๊ท ๊ฐ์ผ๋ก ์ฑ์ฐ๋ ํจ์๋ฅผ ์์ฑํด์ค. ์๋ฌ ์ฒ๋ฆฌ๋ ํฌํจํด์ค."
"๋น์ ์ 10๋ ๊ฒฝ๋ ฅ์ ์๋์ด Python ๊ฐ๋ฐ์์ ๋๋ค"์ฒ๋ผ ์ญํ ์ ๋ช ํํ ํ๋ฉด ๋ต๋ณ ํ์ง์ด ์ฌ๋ผ๊ฐ.
"๋ค์ ํ์์ผ๋ก ๋ต๋ณํด์ฃผ์ธ์: 1. ๊ฐ์, 2. ์์ธ ์ค๋ช , 3. ์์ ์ฝ๋, 4. ์ฃผ์์ฌํญ"์ฒ๋ผ ๊ตฌ์กฐ๋ฅผ ๋ช ์ํ๋ฉด ์ผ๊ด๋ ๋ต๋ณ์ ๋ฐ์ ์ ์์ด.
์์๋ฅผ ๋ช ๊ฐ ์ ๊ณตํ๋ฉด ์ํ๋ ์คํ์ผ์ ๋ต๋ณ์ ๋ฐ๊ธฐ ์ฌ์:
์์ 1:
์
๋ ฅ: "์๋
"
์ถ๋ ฅ: "์๋
ํ์ธ์! ๋ฌด์์ ๋์๋๋ฆด๊น์?"
์์ 2:
์
๋ ฅ: "๋ ์จ"
์ถ๋ ฅ: "์ฃ์กํ์ง๋ง ์ค์๊ฐ ๋ ์จ ์ ๋ณด๋ ์ ๊ณตํ ์ ์์ต๋๋ค."
์ด์ ๋ค์ ์
๋ ฅ์ ๋ต๋ณํด์ฃผ์ธ์:
์
๋ ฅ: "์๊ฐ"
โก ์ฑ๋ฅ ์ต์ ํ ์ค์ ํ
๊ฐ์ ์ง๋ฌธ์ด ๋ฐ๋ณต๋๋ฉด ๊ฒฐ๊ณผ๋ฅผ ์บ์ฑํด์ ์ฌ์ฌ์ฉํด:
import hashlib
import json
cache = {}
def cached_chat(prompt, model='llama2'):
# ์บ์ ํค ์์ฑ
cache_key = hashlib.md5(
f"{model}:{prompt}".encode()
).hexdigest()
if cache_key in cache:
print("์บ์์์ ๊ฐ์ ธ์ด!")
return cache[cache_key]
response = ollama.chat(
model=model,
messages=[{'role': 'user', 'content': prompt}]
)
result = response['message']['content']
cache[cache_key] = result
return result
๊ธด ์๋ต์ ์คํธ๋ฆฌ๋ฐ์ผ๋ก ๋ฐ์์ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํด. ์ ์ฒด ์๋ต์ ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋น ๋ฅด๊ฒ ๋๊ปด์ ธ!
์๋น์ค ์์ ์ ๋ชจ๋ธ์ ๋ฏธ๋ฆฌ ๋ก๋ํด๋๋ฉด ์ฒซ ์์ฒญ์ด ๋นจ๋ผ์ ธ:
# ์๋ฒ ์์ ์
ollama.chat(model='llama2', messages=[
{'role': 'user', 'content': 'hi'}
])
๐ก๏ธ ํ๋ก๋์ ์ฒดํฌ๋ฆฌ์คํธ
โ ์๋ฌ ์ฒ๋ฆฌ - ๋ชจ๋ API ํธ์ถ์ try-except ์ถ๊ฐ
โ ํ์์์ ์ค์ - ๋ฌดํ ๋๊ธฐ ๋ฐฉ์ง
โ ๋ก๊น - ๋ชจ๋ ์์ฒญ/์๋ต ๋ก๊น
โ ๋ชจ๋ํฐ๋ง - ๋ฆฌ์์ค ์ฌ์ฉ๋ ๋ชจ๋ํฐ๋ง
โ ๋ ์ดํธ ๋ฆฌ๋ฏธํ - ๊ณผ๋ํ ์์ฒญ ๋ฐฉ์ง
โ ์ ๋ ฅ ๊ฒ์ฆ - ์ ์์ ์ ๋ ฅ ํํฐ๋ง
โ ๋ฐฑ์ ์ ๋ต - ๋ชจ๋ธ ํ์ผ ๋ฐฑ์
โ ์ ๋ฐ์ดํธ ๊ณํ - ์ ๊ธฐ์ ์ธ ์ ๋ฐ์ดํธ ์ผ์
โ ๋ฌธ์ํ - API ๋ฌธ์ ์์ฑ
โ ํ ์คํธ - ๋จ์ ํ ์คํธ ๋ฐ ํตํฉ ํ ์คํธ
๐ ๋ชจ๋ํฐ๋ง๊ณผ ๋ฉํธ๋ฆญ
import time
import psutil
import ollama
class OllamaMonitor:
def __init__(self):
self.metrics = {
'total_requests': 0,
'total_tokens': 0,
'total_time': 0,
'errors': 0
}
def monitored_chat(self, model, messages):
start_time = time.time()
try:
response = ollama.chat(model=model, messages=messages)
# ๋ฉํธ๋ฆญ ์
๋ฐ์ดํธ
self.metrics['total_requests'] += 1
self.metrics['total_time'] += time.time() - start_time
# ํ ํฐ ์ ์ถ์ (์ค์ ๋ก๋ response์์ ๊ฐ์ ธ์์ผ ํจ)
tokens = len(response['message']['content'].split())
self.metrics['total_tokens'] += tokens
return response
except Exception as e:
self.metrics['errors'] += 1
raise e
def get_stats(self):
avg_time = (self.metrics['total_time'] /
self.metrics['total_requests']
if self.metrics['total_requests'] > 0 else 0)
return {
'total_requests': self.metrics['total_requests'],
'total_tokens': self.metrics['total_tokens'],
'average_response_time': f"{avg_time:.2f}s",
'error_rate': f"{(self.metrics['errors'] / max(self.metrics['total_requests'], 1) * 100):.2f}%",
'cpu_usage': f"{psutil.cpu_percent()}%",
'memory_usage': f"{psutil.virtual_memory().percent}%"
}
# ์ฌ์ฉ
monitor = OllamaMonitor()
# ์์ฒญ ์ฒ๋ฆฌ
response = monitor.monitored_chat(
model='llama2',
messages=[{'role': 'user', 'content': '์๋
?'}]
)
# ํต๊ณ ํ์ธ
print(monitor.get_stats())
๐ ํ์ต ๋ฆฌ์์ค
๊ณต์ ๋ฌธ์: ollama.ai/docs
GitHub: github.com/ollama/ollama
๋ชจ๋ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ: ollama.ai/library
์ปค๋ฎค๋ํฐ: Discord, Reddit r/LocalLLaMA
๋ธ๋ก๊ทธ: Ollama ๊ณต์ ๋ธ๋ก๊ทธ
YouTube: ๋ค์ํ ํํ ๋ฆฌ์ผ ์์๋ค
๊ทธ๋ฆฌ๊ณ ์ฌ๋ฅ๋ท์์ AI ๊ฐ๋ฐ ์ ๋ฌธ๊ฐ๋ค์ ๊ฐ์๋ ๋ฉํ ๋ง์ ๋ฐ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ! ์ค์ ๊ฒฝํ์ด ํ๋ถํ ์ ๋ฌธ๊ฐ๋ค์๊ฒ ์ง์ ๋ฐฐ์ธ ์ ์๊ฑฐ๋ . ๐ฏ
๐ฌ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์, ์ฌ๊ธฐ๊น์ง ์ ๋ง ๊ธด ์ฌ์ ์ด์์ด! ๐์ฐ๋ฆฌ๋ Ollama๋ฅผ ์ฌ์ฉํด์ ๋ก์ปฌ์์ LLM์ ์คํํ๋ ๋ฐฉ๋ฒ์ ์ฒ์๋ถํฐ ๋๊น์ง ์ดํด๋ดค์ด. ์ค์น๋ถํฐ ์์ํด์ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ, API ํตํฉ, ์ปค์คํ ๋ชจ๋ธ ๋ง๋ค๊ธฐ, ์ฑ๋ฅ ์ต์ ํ, ๋ฌธ์ ํด๊ฒฐ, ๊ทธ๋ฆฌ๊ณ ๊ณ ๊ธ ํ์ฉ ์ฌ๋ก๊น์ง ์ ๋ง ๋ง์ ๊ฑธ ๋ค๋ค์ง. ๐
๐ฆ Ollama๋ ์ฝ๋ค - ๋ณต์กํ ์ค์ ์์ด ๋ช ๋ถ ๋ง์ ๋ก์ปฌ LLM์ ์คํํ ์ ์์ด
๐ ํ๋ผ์ด๋ฒ์๊ฐ ๋ณด์ฅ๋๋ค - ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ๋ก์ปฌ์์ ์ฒ๋ฆฌ๋๋๊น ์์ฌํ๊ณ ์ฌ์ฉํ ์ ์์ด
๐ฐ ๋น์ฉ์ด ๋ค์ง ์๋๋ค - API ํธ์ถ ๋น์ฉ ๊ฑฑ์ ์์ด ๋ฌด์ ํ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅํด
๐จ ์ปค์คํฐ๋ง์ด์ง์ด ์์ ๋กญ๋ค - Modelfile๋ก ๋๋ง์ AI๋ฅผ ๋ง๋ค ์ ์์ด
๐ ์ฑ๋ฅ์ด ์ถฉ๋ถํ๋ค - ์ ์ ํ ํ๋์จ์ด๋ง ์๋ค๋ฉด ์ค์ฉ์ ์ธ ์ฑ๋ฅ์ ๋ผ ์ ์์ด
๐ ํตํฉ์ด ์ฝ๋ค - Python, JavaScript ๋ฑ ๋ค์ํ ์ธ์ด์ ํ๋ ์์ํฌ์์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ด
๋ฌผ๋ก ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ LLM(ChatGPT, Claude ๋ฑ)์ด ๋ ๊ฐ๋ ฅํ ๊ฑด ์ฌ์ค์ด์ผ. ํ์ง๋ง Ollama๋ก ๋ก์ปฌ์์ ๋๋ฆฌ๋ ๋ชจ๋ธ๋ค๋ ๋๋ถ๋ถ์ ์ค์ฉ์ ์ธ ์์ ์๋ ์ถฉ๋ถํด. ๊ทธ๋ฆฌ๊ณ ๋ฌด์๋ณด๋ค ๋ด ์ปดํจํฐ์์ AI๊ฐ ๋์๊ฐ๋ค๋ ๊ฒ ์ ๋ง ๋ฉ์ง์ง ์์? ๐
1. ์ง์ ์ค์นํด์ ์ฌ๋ฌ ๋ชจ๋ธ์ ์คํํด๋ด
2. ๊ฐ๋จํ ํ๋ก์ ํธ๋ถํฐ ์์ํด๋ด (์ฑ๋ด, ์์ฝ ๋๊ตฌ ๋ฑ)
3. Modelfile๋ก ์ปค์คํ ๋ชจ๋ธ์ ๋ง๋ค์ด๋ด
4. ์ปค๋ฎค๋ํฐ์ ์ฐธ์ฌํด์ ๋ค๋ฅธ ์ฌ๋๋ค์ ๊ฒฝํ์ ๋ฐฐ์๋ด
5. ์ค์ ํ๋ก๋์ ํ๊ฒฝ์ ์ ์ฉํด๋ด
๊ทธ๋ฆฌ๊ณ ํน์ ๋ ๊น์ด ์๋ ํ์ต์ด๋ ์ค์ ํ๋ก์ ํธ ๋์์ด ํ์ํ๋ค๋ฉด, ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์ ์ ๋ฌธ๊ฐ๋ค์ ๋์์ ๋ฐ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ. ํผ์ ์ฝ์งํ๋ ๊ฒ๋ณด๋ค ๊ฒฝํ ๋ง์ ์ฌ๋์๊ฒ ๋ฐฐ์ฐ๋ ๊ฒ ํจ์ฌ ๋น ๋ฅด๊ณ ํจ์จ์ ์ด๊ฑฐ๋ ! ๐ค
์, ์ด์ ๋น์ ์ฐจ๋ก์ผ! Ollama๋ฅผ ์ค์นํ๊ณ ์ฒซ ๋ฒ์งธ ๋ก์ปฌ LLM์ ์คํํด๋ด. ๊ทธ๋ฆฌ๊ณ ๋ฌด์์ ๋ง๋ค์ง ์์ํด๋ด. ๊ฐ๋ฅ์ฑ์ ๋ฌด๊ถ๋ฌด์งํด! ๐
ํ์ด์ ๋น์ด! ๊ทธ๋ฆฌ๊ณ ๋ฉ์ง AI ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด๋ด! ํ์ดํ ! ๐ชโจ
๊ด๋ จ ํค์๋
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.

๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.