[κ°μ΄λ] Pythonμμ Ollama μ¬μ©νκΈ°: μ€μΉλΆν° AI μμ΄μ νΈ λ§λ€κΈ°
μλ³Έ κ²μκΈ: https://velog.io/@euisuk-chung/κ°μ΄λ-Pythonμμ-Ollama-μ¬μ©νκΈ°-μ€μΉλΆν°-AI-μμ΄μ νΈ-λ§λ€κΈ°
π κ°μ
Ollamaλ λ‘컬 νκ²½μμ λκ·λͺ¨ μΈμ΄ λͺ¨λΈ(LLM, Large Language Model)μ κ°λ¨ν μ€ννκ³ Python νλ‘μ νΈμ ν΅ν©ν μ μλλ‘ λμμ£Όλ νλ μμν¬μ
λλ€. ν΄λΉ ν¬μ€νΈμμλ Ollamaμ μ€μΉ λ°©λ²λΆν° Python SDK μ¬μ©λ², μ€μ νμ© μμ (μ±λ΄ ꡬν, μλν μμ΄μ νΈ κ°λ°)κΉμ§ λ¨κ³λ³λ‘ μ΄ν΄λ΄
λλ€. (μ¬μ© λͺ¨λΈμ κ΅μ° LLMμΈ exaone3.5:7.8b
μ
λλ€.)
Ollamaμ Exaone 3.5 μκ°
Ollama
λ Dockerμ²λΌ μ¬μ λΉλλ λͺ¨λΈ ν¨ν€μ§λ₯Ό λ‘컬μμ pull λ°μ μ€νν μ μλλ‘ μ€κ³λ μ€νμμ€ νλ«νΌμ
λλ€. λͺ¨λΈ μ€νμ νμν κ°μ€μΉ, μ€μ , λ°μ΄ν° λ±μ νλμ ν¨ν€μ§(Modelfile)λ‘ λ¬Άμ΄ CLIλ REST APIλ‘ μμ½κ² μ¬μ©ν μ μμ΅λλ€.
Exaone 3.5
λ LG AIμ°κ΅¬μμμ 곡κ°ν λͺ¨λΈλ‘ νκ΅μ΄μ μ΅μ νλ λν μΈμ΄ λͺ¨λΈλ‘, λ¬Έμ μμ½, μ§μμλ΅, λ¬Έλ§₯ μ΄ν΄ λ±μμ λμ μ±λ₯μ 보μ
λλ€. LLM μμ§λμ΄λ§ κ΄μ μμλ νκΈ κΈ°λ° νλ‘μ νΈμ μ ν©ν μ νμ§μ
λλ€.
μ λ κ°μ₯ μ΅μ μ λμ¨ EXAONE 3.5:7.8b
λͺ¨λΈμ μ¬μ©νμ¬ μ€μ΅μ μ§νν΄λ³΄λλ‘ νκ² μ΅λλ€.
Ollama μ€μΉ λ° Python μ°λ
1. Ollama μμ§ μ€μΉ
macOS / windowsOS
μ λ§ν¬μμ ν΄λΉ OSμ λ§λ installerλ₯Ό μ€μΉνμ€ μ μμ΅λλ€.
Linux
리λ μ€λ μλ μ½λλ₯Ό μ€νν΄μ μ€μΉνμ€ μ μμ΅λλ€.
1
2
# Linux
curl -sS https://ollama.ai/install.sh | bash
2. λͺ¨λΈ λ€μ΄λ‘λ
(ν°λ―Έλμμ μ€ν)
1
ollama pull exaone3.5:7.8b
3. λͺ¨λΈ μ€ννκΈ°
(ν°λ―Έλμμ μ€ν)
1
ollama run exaone3.5:7.8b
3. Python SDK μ€μΉ
ollamaλ₯Ό νμ΄μ¬μμ μ€ννκΈ° μν΄μλ μλ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ€μΉν΄μΌ ν©λλ€.
1
pip install ollama
첫 λ²μ§Έ μμ : ν둬ννΈ κΈ°λ° ν μ€νΈ μμ±
1
2
3
4
import ollama
result = ollama.generate(model='exaone3.5:7.8b', prompt='μ°μ£Όλ μ μ΄λμ΄κ°μ?')
print(result['response'])
μ€μ νμ© 1: νλΌμ΄λΉ AI μ±λ΄ ꡬμΆ
μλ ν¨μλ₯Ό ν΅ν΄ chatSLM.py
λ₯Ό μ μνλ©΄ λ°λ‘ μ±λ΄μ²λΌ μ¬μ©νμ€ μ μμ΅λλ€!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import ollama
model_name = 'exaone3.5:7.8b'
messages = [
{"role": "system", "content": "λΉμ μ μΉμ ν μΈκ³΅μ§λ₯ μ΄μμ€ν΄νΈμ
λλ€."},
{"role": "user", "content": "μλ
νμΈμ!"},
]
response = ollama.chat(model=model_name, messages=messages)
print("Bot:", response.message.content)
while True:
user_input = input("You: ")
if not user_input:
break
messages.append({"role": "user", "content": user_input})
response = ollama.chat(model=model_name, messages=messages)
answer = response.message.content
print("Bot:", answer)
messages.append({"role": "assistant", "content": answer})
Run python file
1
$ python chatSLM.py
π€ λν μμ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Bot: μλ
νμΈμ! π μ΄λ»κ² λμλ릴κΉμ? 무μμ΄ κΆκΈνμ κ°μ? π
You: μλ
! λ°κ°μ
Bot: μλ
νμΈμ! π νμν©λλ€! 무μμ λμλ릴κΉμ? π
μ΄λ€ μ£Όμ μ λν΄ μ΄μΌκΈ°νκ³ μΆμΌμ κ°μ? π£οΈ
You: μ€μ½μ΄ λμΌ?
Bot: "μ€μ½"μ΄λΌλ μ©μ΄κ° λ¬Έλ§₯μ λ°λΌ μ‘°κΈ λ€λ₯Ό μ μμ§λ§,
μ£Όλ‘ λ κ°μ§ μλ―Έλ‘ μ΄ν΄λ μ μμ΅λλ€:
1. **λλ¬Ό**: μ€μ½μ μν리카μ μμμ μΌλΆ μ§μμ μμνλ
μμ ν¬μμ λλ¬Όλ‘, μ’
μ’
"μμ κ³ μμ΄"λΌκ³ λΆλ¦¬λ©°
μ νν νλͺ
μ _Felis serval_μ
λλ€.
2. **μΈμ΄/μμ΄**: νΉμ μ§μμμ μ°μ΄λ μμ΄λ λ³μΉμΌ μλ μμ΅λλ€.
ꡬ체μ μΈ λ§₯λ½μ΄ μλ€λ©΄ λ μ νν μ€λͺ
ν΄ λ릴 μ μμ΄μ.
You: λΉ μμ² μ€λ κ²λ μ€μ½ μλκ°?
Bot: λ§μμ! π§οΈ "μ€μ½"μ νΉν **μ§§κ³ κ°λ ¬ν μ§μ€ νΈμ°**λ₯Ό κ°λ¦¬ν€λ λ§λ‘λ μμ£Ό μ¬μ©λ©λλ€.
μν리카 μ΄λ κΈ°νμμ νν λ³Ό μ μλ νμμΌλ‘,
κ°μκΈ° μμλμ΄ λͺ λΆμμ λͺ μκ° λμ κ΅μ₯ν μΈκ² μμμ§λ€κ°
κΈμμ€λ½κ² λ©μΆλ νΉμ±μ κ°μ§κ³ μμ΅λλ€.
μ΄λ° νΉμ§μ μΈ λ μ¨ νμμ μ€λͺ
ν λ "μ€μ½"μ΄λΌλ λ¨μ΄κ° μ°μ
λλ€! π
μ€μ νμ© 2: λ¬Έμ μλ μμ½
μ½λ:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import ollama
text = '''
Ollamaλ λκ·λͺ¨ μΈμ΄ λͺ¨λΈ(LLM)μ λ‘컬μμ μ§μ μ€νν μ μλλ‘ λμμ£Όλ μ€νμμ€ λꡬμ
λλ€.
μ΄λ₯Ό ν΅ν΄ μ¬μ©μλ μΈν°λ· μ°κ²° μμ΄λ κ³ μ±λ₯ μΈμ΄ λͺ¨λΈμ μ€νν μ μμΌλ©°,
μΈλΆ API νΈμΆ μμ΄ ν
μ€νΈ μμ±, λ¬Έμ μμ½, μ§λ¬Έ μλ΅ λ±μ λ€μν μμ°μ΄ μ²λ¦¬(NLP) μμ
μ μνν μ μμ΅λλ€.
νΉν, λ―Όκ°ν λ°μ΄ν°λ₯Ό λ€λ£¨λ νκ²½μμλ λ°μ΄ν° νλΌμ΄λ²μλ₯Ό 보μ₯ν μ μκ³ ,
ν΄λΌμ°λ κΈ°λ° μκΈ λΆλ΄ μμ΄ μμμ ν¨μ¨μ μ¬μ©μ΄ κ°λ₯ν΄ λΉμ© μ κ°μλ ν° λμμ΄ λ©λλ€.
Ollamaλ λ€μν μ€νμμ€ λͺ¨λΈμ μ§μνλ©°, λͺ
λ Ήμ€ μΈν°νμ΄μ€(CLI) λ° Python SDKλ₯Ό ν΅ν΄ μμ½κ² ν΅ν©ν μ μμ΅λλ€.
'''
prompt = f"""
λ€μ ν
μ€νΈλ₯Ό ν λ¬Έμ₯μΌλ‘ μμ½ν΄ μ£ΌμΈμ:
\"\"\"\n{text}\n\"\"\"
"""
result = ollama.generate(model='exaone3.5:7.8b', prompt=prompt)
print("Summary:", result['response'])
μΆλ ₯:
μ€μ νμ© 3: μ½λ μμ²νκΈ°
μ½λ:
1
2
3
4
5
6
7
import ollama
code_prompt = "μ«μκ° μμ(Prime Number)μΈμ§ νμΈνλ μ½λ μμ±ν΄μ€"
response = ollama.generate(model='exaone3.5:7.8b', prompt=code_prompt)
print(response['response'])
μΆλ ₯:
μ€μ νμ© 4: ν¨μ νΈμΆ κΈ°λ° AI μμ΄μ νΈ λ§λ€κΈ°
1. ν΄ ν¨μ μ μ (κ³μ° κΈ°λ₯ μμ)
1
2
3
def add_two_numbers(a: int, b: int) -> int:
"""λ μ«μλ₯Ό λν΄ λ°νν©λλ€."""
return a + b
2. μμ€ν λ©μμ§ + μ¬μ©μ μ§λ¬Έ μ λ ₯
1
2
3
4
5
6
7
8
9
system_message = {
"role": "system",
"content": "λΉμ μ μν κ³μ°μ λμμ£Όλ AIμ
λλ€. νμμ 'add_two_numbers' ν¨μλ₯Ό νΈμΆν΄ κ³μ°νμΈμ."
}
user_message = {
"role": "user",
"content": "10 + 10μ μΌλ§μΈκ°μ?"
}
messages = [system_message, user_message]
3. λͺ¨λΈ μ€ν λ° ν΄ νΈμΆ μ²λ¦¬
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
model='exaone3.5:7.8b'
response = ollama.chat(
model=model,
messages=messages,
tools=[add_two_numbers]
)
if response.message.tool_calls:
for tool_call in response.message.tool_calls:
func_name = tool_call.function.name
args = tool_call.function.arguments
if func_name == "add_two_numbers":
result = add_two_numbers(**args)
print("Function output:", result)
messages.append({"role": "assistant", "content": f"The result is {result}."})
follow_up = ollama.chat(model=model, messages=messages)
print("Assistant (final):", follow_up.message.content)
μ΄? μλλλ°μ?
=> λ€ λ§μ΅λλ€! toolμ μ¬μ©ν μ μλ λͺ¨λΈμ μ νμ μΈλ°μ π
Ollamaμ μ¬λΌμ μλ μμ¬μ λͺ¨λΈμ toolμ μ§μνκ³ μμ§ μμ΅λλ€:
Ollamaμ μ¬λΌμ¨ λͺ¨λΈ μ€ toolμ μ§μνλ λͺ¨λΈμ λνμ μΌλ‘ llama λͺ¨λΈμ΄ μμ£ !
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import ollama
model_name = 'llama3.1:8b'
response = ollama.chat(
model= model_name,
messages=messages,
tools=[add_two_numbers]
)
if response.message.tool_calls:
for tool_call in response.message.tool_calls:
func_name = tool_call.function.name
args = tool_call.function.arguments
if func_name == "add_two_numbers":
result = add_two_numbers(**args)
print("Function output:", result)
messages.append({"role": "assistant", "content": f"The result is {result}."})
follow_up = ollama.chat(model=model_name, messages=messages)
print("Assistant (final):", follow_up.message.content)
llama3.1:8b
λ₯Ό μ¬μ©ν΄μ μ€ννλ©΄ ν¨μκ° μ λλ‘ μ€νλλ κ²μ νμΈν μ μμ΅λλ€.
(μ°Έκ³ ) π§ μλ λ°©μ: Function Callingμ νλ¦
-
λͺ¨λΈμ ν¨μ νΈμΆμ βμμ²βν©λλ€.
- ν둬ννΈλ λν νλ¦μ ν΅ν΄ ν¨μ μ΄λ¦κ³Ό νλΌλ―Έν°λ₯Ό JSON νμμΌλ‘ λ°νν©λλ€.
- μ:
{"function": "add_two_numbers", "arguments": {"a": 10, "b": 10}}
-
Ollama SDKλ μ΄ μμ²μ
tool_calls
ννλ‘ ν¬μ°©ν©λλ€.response.message.tool_calls
λ‘ μ κ·Ό κ°λ₯- μ΄ λ¨κ³μμλ λͺ¨λΈμ λ¨μ§ νΈμΆ βμ μβμ ν μνμ λλ€.
-
κ°λ°μ(Python μ½λ)κ° ν΄λΉ μμ²μ νμ±νμ¬ μ€μ Python ν¨μ νΈμΆ
- μ:
add_two_numbers(**tool_call.function.arguments)
- μ:
-
κ²°κ³Όλ₯Ό λ€μ LLMμ λκΈ°κ³ νμ μλ΅ μμ±
- λ€μ
ollama.chat()
μ νΈμΆνμ¬The result is 20.
κ°μ νμ λ°νλ₯Ό μμ±νκ² ν©λλ€.
- λ€μ
(μ°Έκ³ ) π μνμ€ λμ
λꡬ νΈμΆμ λμνν΄λ³΄λ©΄ λ€μκ³Ό κ°μ΄ 그릴 μ μμ΅λλ€:
1
2
3
4
5
6
7
8
9
10
11
12
13
[User Message] βββΆ [LLM: I want to call add_two_numbers(10, 10)]
β
βΌ
[SDK detects tool_call]
β
βΌ
[Python code executes add_two_numbers(10, 10)]
β
βΌ
[Result (20) is inserted into conversation history]
β
βΌ
[LLM generates follow-up: "The result is 20."]
λ§λ¬΄λ¦¬
μ΄ κΈμμλ LLM κΈ°λ° μ ν리μΌμ΄μ
μ λΉ λ₯Έ 건μ€μΌλ‘ κ°λ₯νκ² ν΄μ£Όλ Ollamaμ νμ κΈ°λ₯κ³Ό Python μ°λ λ°©λ²μ μ΄ν΄λ³΄μμ΅λλ€. νΉν exaone3.5:7.8b
μ κ°μ κ΅μ¬ LLMμ μ¬μ©ν κ²½μ°, νκ΅μ΄ νμ μ±λ₯μ λμ΄λ©° λλ κ°ν νλΌμ΄λ²μμ λ°μ± μλλ₯Ό ν립ν μ μμ΅λλ€.
λ§μ§λ§μΌλ‘ Ollama μ£Όμ API λ° Python ν¨μλ₯Ό μ 리νκ³ , μ΄λ² ν¬μ€νΈλ₯Ό λ§λ¬΄λ¦¬ν΄λ³΄κ² μ΅λλ€!! π
Ollama μ£Όμ API λ° Python ν¨μ μ 보
π’ 1. λͺ¨λΈ μμ± λ° ν μ€νΈ μμ± (Text Generation)
/api/generate
: μ 곡λ ν둬ννΈμ κΈ°λ°νμ¬ ν μ€νΈλ₯Ό μμ±-
μ£Όμ νλΌλ―Έν°:
model
: μ¬μ©ν λͺ¨λΈ μ΄λ¦ (μ:llama3
,gemma
)prompt
: μ λ ₯ ν μ€νΈstream
: μ€νΈλ¦¬λ° μλ΅ μ¬λΆ (κΈ°λ³Έκ°:true
)options
:temperature
,top_k
,top_p
λ± μ€μ
-
/api/chat
: λνν μλ΅ μμ± (λ¬Έλ§₯ μ μ§μ©)model
,messages
,stream
λ± μ¬μ©
π¦ 2. λͺ¨λΈ λͺ©λ‘ λ° μ 보 μ‘°ν (Model Info)
/api/tags
λλ/api/ps
: λ€μ΄λ‘λλ λͺ¨λΈ λͺ©λ‘ (docker ps λλ)/api/show
: νΉμ λͺ¨λΈ μ 보 (νλΌλ―Έν°, λΌμ΄μ μ€ λ±)
π₯ 3. λͺ¨λΈ λ€μ΄λ‘λ λ° κ΄λ¦¬
-
/api/pull
: λͺ¨λΈ λ€μ΄λ‘λname
,stream
,insecure
λ± μ€μ
/api/push
: λ‘컬 λͺ¨λΈ μ λ‘λ (컀μ€ν 곡μ μ)/api/copy
: λ‘컬 λͺ¨λΈ 볡μ¬/api/delete
: λ‘컬 λͺ¨λΈ μμ
π§ 4. μλ² λ© μμ± (Embeddings)
-
/api/embeddings
: μ λ ₯ ν μ€νΈ μλ² λ© λ²‘ν° μμ±- κ²μ, μ μ¬λ λΉκ΅, κ΅°μ§ν λ±μ νμ©
- μ£Όμ νλΌλ―Έν°:
model
,prompt
,options
π μ£Όμ Python ν¨μ λ§€ν
ollama.list()
β/api/tags
λλ/api/ps
(λͺ¨λΈ λͺ©λ‘)ollama.show(name)
β/api/show
ollama.pull(name, stream=False)
β/api/pull
ollama.generate(model, prompt, stream=False)
β/api/generate
ollama.chat(model, messages, stream=False)
β/api/chat
ollama.embeddings(model, prompt)
β/api/embeddings
ollama.ps()
β/api/ps
(μ€ν μ€ λͺ¨λΈ νμΈ)ollama.delete(name)
β/api/delete
ollama.copy(source, destination)
β/api/copy
μ΄ μμ½μ μ°Έκ³ νμ¬ Ollama SDKλ₯Ό λ κΉμ΄ νμ©ν΄ 보μΈμ!
μ½μ΄μ£Όμ μ κ°μ¬ν©λλ€ πΆ