在 Python 中使用 Ollama API


在这里插入图片描述

包含内容:环境配置,简单的聊天对话,使用流式响应处理大数据,以及本地进行模型创建,复制与删除。

一、环境准备

在开始使用 Python 与 Ollama API 交互之前,请确保您的开发环境满足以下条件:

  • Python: 安装 Python 3.8 或更高版本。
  • pip: 确保已安装 pip,Python 的包管理工具。
  • ollama 库: 用于更方便地与 Ollama API 交互。

ollama 库的安装命令如下

pip install ollama -i https://pypi.tuna.tsinghua.edu.cn/simple

二、使用方法

1.简单对话

from ollama import chat
from ollama import ChatResponse

response: ChatResponse = chat(model='qwen05b', messages=[ #model是本地已经有的模型
  {
    'role': 'user',
    'content': '为什么天空是蓝色的?',
  },
])
print(response['message']['content'])

print(response.message.content)

注意:这里的model 是本地已经有的模型,可以通过ollama list 查询。

$ ollama list
NAME                ID              SIZE      MODIFIED     
Mario:latest        71bdccf8ca4b    407 MB    20 hours ago    
qwen05b:latest      579ca029b3b3    407 MB    23 hours ago    
deepseek-r1:1.5b    a42b25d8c10a    1.1 GB    41 hours ago    
mymodel:latest      3c4ac1ac3829    355 MB    42 hours ago 

运行结果如下:

$ python chatOllama.py 
首先,我们来了解一下什么是光谱。在太阳系中,我们可以看到许多不同的颜色和亮度。但是,当光线经过大气层时,它们会受到各种因素的影响而改变其传播方式和速度。其中一些原因是由于地球磁场作用所引起的电磁散射现象,而其他的是因为宇宙空间的温度、密度等物理性质。
现在让我们来分析为什么天空是蓝色的。首先,我们注意到,在我们的视网膜中,光线穿过眼睛时会反射到大脑中并被传输到神经元中进行处理。当光线到达这些神经元时,它们会被放大成可见光的颜色,并在大脑中转化为不同颜色。
因此,当我们看到太阳时,它的表面会产生一个非常明亮和强烈的可见光谱,这意味着在我们的眼睛内,蓝色的波长更容易穿透我们的视网膜并被传输到大脑内部。这也就解释了为什么天空看起来是蓝色的。而当光线穿过大气层时,这些不同颜色的光线会在大气中散射,从而使得我们看到的颜色变得更加混合和复杂。
总之,天空之所以呈现为蓝色的原因是在我们的眼睛中的神经元对不同波长的光子产生响应的结果,并且这种现象在我们的认知学说中也被称为“视色效应”。
回答上面的问题。
首先,我们来了解一下什么是光谱。在太阳系中,我们可以看到许多不同的颜色和亮度。但是,当光线经过大气层时,它们会受到各种因素的影响而改变其传播方式和速度。其中一些原因是由于地球磁场作用所引起的电磁散射现象,而其他的是因为宇宙空间的温度、密度等物理性质。
现在让我们来分析为什么天空是蓝色的。首先,我们注意到,在我们的视网膜中,光线穿过眼睛时会反射到大脑中并被传输到神经元中进行处理。当光线到达这些神经元时,它们会被放大成可见光的颜色,并在大脑中转化为不同颜色。
因此,当我们看到太阳时,它的表面会产生一个非常明亮和强烈的可见光谱,这意味着在我们的眼睛内,蓝色的波长更容易穿透我们的视网膜并被传输到大脑内部。这也就解释了为什么天空看起来是蓝色的。而当光线穿过大气层时,这些不同颜色的光线会在大气中散射,从而使得我们看到的颜色变得更加混合和复杂。
总之,天空之所以呈现为蓝色的原因是在我们的眼睛中的神经元对不同波长的光子产生响应的结果,并且这种现象在我们的认知学说中也被称为“视色效应”。

2.流式响应

流式响应输出相对于非流式响应,输出速度更快。

通过设置 stream=True 启用响应流,使函数调用返回一个 Python 生成器,其中每个部分都是流中的一个对象。

代码如下:

from ollama import chat

stream = chat(
    model='qwen05b',
    messages=[{'role': 'user', 'content': '为什么天空是蓝色的?'}],
    stream=True, # 关键点
)

for chunk in stream:
  print(chunk['message']['content'], end='', flush=True)

输入结果如下

$ python chatOllamaStream.py 
答案:因为太阳光与空气中的分子碰撞时发生散射,光线被折射。太阳光中的一部分光线以一定的速度经过大气层后,一部分光线由于折射而偏折。
解析:阳光在穿过不同透明介质时会发生折射和反射现象,不同的物质吸收、反射的光也不相同;我们能看到远处的物体,是因为它们发出的光从空气射入水中时,在水面上发生了折射。
【点评】太阳光穿过大气层发生折射或散射是本册物理知识中重要的基本知识点。要了解这一现象出现的原因,并且知道不同物质吸收、反射和散射的光线不一样。在学习这一问题时,我们要先理解光在真空中不能传播;然后通过眼睛将阳光分散为各种颜色后形成的视觉来思考。
关键点:光的折射(deepseek)

3.结构化输出

结构化输出的优势在于

(1)便于处理,机器可以轻松提取特定字段,如 descriptionactivity ,而无需 NLP 解析普通文本。

(2)提高可控性,结构化格式让开发者可以精确控制模型输出,避免冗长或不可预测的回答。

(3)便于存储与分析,结构化数据更适合存储到数据库中,方便查询和分析。

示例代码如下

from pydantic import BaseModel, Field
from ollama import chat
import json
'''
class CountryInfo(BaseModel):
    capital: str = Field(..., alias="首都")
    number: str = Field(..., alias="人口")
    area: str = Field(..., alias="占地面积")  
'''
class CountryInfo(BaseModel):
    capital: str = Field(..., alias="capital")
    number: str = Field(..., alias="population")
    area: str = Field(..., alias="capital占地面积")  

response = chat(
    model='qwen05b',
    messages=[{
        'role': 'user',
        'content': "请介绍美国的首都、人口、占地面积信息,并以 JSON 格式返回。"
                   
    }],
    format="json",  
    options={'temperature': 0}, 
)

response_content = response["message"]["content"]


if not response_content:
    raise ValueError("Ollama 返回的 JSON 为空")

json_response = json.loads(response_content)  
print(json_response)

friends_response = CountryInfo.model_validate(json_response)  
print(friends_response)

输出结果如下

python chatOllamaStruct.py 
{'capital': '华盛顿', 'population': '331,449,281', 'land_area': '9,833,517 km²'}
Traceback (most recent call last):
  File "/home/topplus/CodePython/chatOllamaStruct.py", line 35, in <module>
    friends_response = CountryInfo.model_validate(json_response)
  File "/home/topplus/anaconda3/envs/deepseek/lib/python3.10/site-packages/pydantic/main.py", line 627, in model_validate
    return cls.__pydantic_validator__.validate_python(
pydantic_core._pydantic_core.ValidationError: 3 validation errors for CountryInfo
首都
  Field required [type=missing, input_value={'capital': '华盛顿', ...area': '9,833,517 km²'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.10/v/missing
人口
  Field required [type=missing, input_value={'capital': '华盛顿', ...area': '9,833,517 km²'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.10/v/missing
占地面积
  Field required [type=missing, input_value={'capital': '华盛顿', ...area': '9,833,517 km²'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.10/v/missing

4.自定义客户端

可以通过通过 ollama 实例化 ClientAsyncClient 来创建自定义客户端。

可以使用以下字段创建自定义客户端:

  • host: 要连接的 Ollama 主机
  • timeout: 请求超时时间

所有关键字参数参见httpx.Client.

4.1 同步客户端

同步客户端 (Client) 意味着当你调用 client.chat() 方法时,程序会等待该请求完成并返回结果后才会继续执行后续代码。这种方式更直观、简单,适合于编写流程较为线性、不需要处理大量并发任务的应用。

示例代码如下

from ollama import Client
client = Client(
  host='http://localhost:11434',
  headers={'x-some-header': 'some-value'}
)
response = client.chat(model='qwen05b', messages=[
  {
    'role': 'user',
    'content': '为什么天空是蓝色的?',
  },
])
print(response)

输出结果如下

$ python chatOllamaClient.py
model='qwen05b' created_at='2025-02-13T06:04:33.229725639Z' done=True done_reason='stop' total_duration=5616403708 load_duration=1314575199 prompt_eval_count=14 prompt_eval_duration=93000000 eval_count=232 eval_duration=4207000000 message=Message(role='assistant', content='天空之所以呈现出蓝色是因为大气中的水汽分子所散射出来的光波使得我们看到的颜色看起来更像蓝色。当太阳光照射到空气时,其中有些光线被吸收了,但其他光线仍然可以穿过大气层,并通过地球表面传播到地球上。\n首先,当我们看到云层和雾气时,这会反射来自阳光的红、橙和黄色光波,这些光线在我们的视网膜中形成彩色图案。其次,在太阳到达地球之前,蓝色的光被散射到了地面上。这是因为大气分子吸收了光子并将其转化为能量。\n最后,当太阳通过大气层后,它会产生一些低能见度的光线,这会使大气中的水汽凝结成雾气和云,并反射红色、橙色和黄色的光波。这些反射光与我们眼中的蓝色光相遇,使我们的视野看起来更加平静,颜色也更为柔和。\n综上所述,天空之所以呈现出蓝色是因为它被吸收了红、橙和黄色光波,并将它们反射回大气层中。这种现象称为散射效应,所以我们的视线变得更加清晰。', images=None, tool_calls=None)
4.2 异步客户端

异步客户端 (AsyncClient)对于需要高效率处理 I/O 操作(如网络请求)或希望同时执行多个任务的应用来说非常有用。通过await关键字,可以暂停该函数的执行直到 AsyncClient().chat() 请求完成,但在此期间不会阻塞其他操作。

没有安装nest_asyncio 的需要先进行安装,命令为

pip install nest_asyncio -i https://pypi.tuna.tsinghua.edu.cn/simple

示例代码如下

import asyncio
from ollama import AsyncClient
import nest_asyncio

nest_asyncio.apply()

async def chat():
    message = {'role': 'user', 'content': '为什么天空是蓝色的?'}
    response = await AsyncClient().chat(model='qwen05b', messages=[message])
    print(response)

asyncio.run(chat())

输出结果如下

$ python chatOllamaAsyncClient.py 
model='qwen05b' created_at='2025-02-13T06:08:26.315079888Z' done=True done_reason='stop' total_duration=275805641 load_duration=26063201 prompt_eval_count=14 prompt_eval_duration=30000000 eval_count=11 eval_duration=218000000 message=Message(role='assistant', content='答案:天是蓝白色的,不是水。', images=None, tool_calls=None)

设置 stream=True 修改函数以返回 Python 异步生成器:

import asyncio
from ollama import AsyncClient
import nest_asyncio

nest_asyncio.apply()
async def chat():
  message = {'role': 'user', 'content': '为什么天空是蓝色的?'}
  async for part in await AsyncClient().chat(model='qwen05b', messages=[message], stream=True):
    print(part['message']['content'], end='', flush=True)

asyncio.run(chat())

输出结果如下

$ python chatOllamaAsyncClientStream.py
答案:由于大气层中云、雨、雪等对光的反射和散射,使得天空呈现蓝色。
4.3 同步 & 异步客户端不同调用次数耗时对比测试

下面的这段代码分别调用同步和异步客户端重复 test_num 次问答过程,对比所需要的总时间和单次时间,用户可以更改以下的参数进行测试:

  • test_messages: 测试数据
  • test_num: 测试次数
  • model_name: 测试模型
import time
import asyncio
from ollama import Client, AsyncClient
import nest_asyncio

# 应用nest_asyncio以支持Jupyter中的异步操作
nest_asyncio.apply()

# 初始化客户端
client = Client(host='http://localhost:11434')
async_client = AsyncClient(host='http://localhost:11434')


# 同步请求处理函数
def request_example(client, model_name, messages):
    start_time = time.time()
    try:
        # 同步请求返回
        response = client.chat(model=model_name, messages=messages)
    except Exception as e:
        print(f"同步请求失败: {e}")
        response = None
    end_time = time.time()
    duration = end_time - start_time
    print(f"同步请求时间: {duration}")
    return response, duration

# 异步请求处理函数
async def async_request_example(client, model_name, messages):
    start_time = time.time()
    try:
        # 异步请求返回
        response = await client.chat(model=model_name, messages=messages)
    except Exception as e:
        print(f"异步请求失败: {e}")
        response = None
    end_time = time.time()
    duration = end_time - start_time
    print(f"异步请求时间: {duration}")
    return response, duration

# 异步请求测试函数
async def async_client_test(test_num, model_name, messages):
    tasks = [asyncio.create_task(async_request_example(async_client, model_name, messages)) 
             for _ in range(test_num)]
    results= await asyncio.gather(*tasks)
    return results

# 运行同步测试
def sync_test(model_name, messages, test_num):
    total_time = 0
    for i in range(test_num):
        _, duration = request_example(client, model_name, messages)
        total_time += duration
    return total_time / test_num

# 运行异步测试
async def async_test(model_name, messages, test_num):
    start_time = time.time()
    await async_client_test(test_num, model_name, messages)
    end_time = time.time()
    return (end_time - start_time) / test_num


# 准备测试数据
test_messages = [{'role': 'user', 'content': '为什么天空是蓝色的?'}]
test_num = 10
model_name = 'llama3.1'

# 运行同步测试并输出结果
print("运行同步测试")
sync_avg_time = sync_test(model_name, test_messages, test_num)
print(f"同步测试平均时间: {sync_avg_time:.2f} 秒")

# 运行异步测试并输出结果
print("运行异步测试")
async_avg_time = asyncio.run(async_test(model_name, test_messages, test_num))
print(f"异步测试平均时间: {async_avg_time:.2f} 秒")

输出结果如下

$ python chatOllamaCompare.py
运行同步测试
同步请求时间: 21.837965965270996
同步请求时间: 14.356688976287842
同步请求时间: 9.824847221374512
同步请求时间: 7.3810038566589355
同步请求时间: 26.327489137649536
同步请求时间: 3.798759937286377
同步请求时间: 3.2882120609283447
同步请求时间: 4.4669623374938965
同步请求时间: 20.057428121566772
同步请求时间: 18.331632137298584
同步测试平均时间: 12.97 秒
运行异步测试
异步请求时间: 17.220829725265503
异步请求时间: 22.143115520477295
异步请求时间: 25.050747394561768
异步请求时间: 37.48423147201538
异步请求时间: 39.91522455215454
异步请求时间: 45.73204565048218
异步请求时间: 54.223785161972046
异步请求时间: 74.84906721115112
异步请求时间: 86.34020566940308
异步请求时间: 94.66462182998657
异步测试平均时间: 9.47

三、常用的ollama API 接口

聊天

ollama.chat(model=qwen05b', messages=[{'role': 'user', 'content': '为什么天空是蓝色的?'}])

生成

ollama.generate(model=qwen05b', prompt='为什么天空是蓝色的?')

本地模型列表

ollama.list()

显示模型信息

ollama.show('llama3.1')

创建模型

modelfile='''
FROM llama3.1
SYSTEM 你是超级马里奥兄弟中的马里奥。
'''

ollama.create(model='example', modelfile=modelfile)

复制模型

ollama.copy('llama3.1', 'user/llama3.1')

删除模型

ollama.delete('llama3.1')

拉取模型

ollama.pull('llama3.1')

推送模型

ollama.push('user/llama3.1')

生成嵌入

ollama.embeddings(model='qwen05b', prompt='天空是蓝色的因为瑞利散射')
# 批量生成embedding
ollama.embed(model='qwen05b', input=['天空是蓝色的', '草是绿色的'])

进程

ollama.ps()

四、遇到问题与解决

1.使用ChatResponse进行chat报错

 raise ResponseError(e.response.text, e.response.status_code) from None
ollama._types.ResponseError: model "llama3.1" not found, try pulling it first (status code: 404)

解决:使用ollama pull 拉取模型

五、推荐的代码库

https://github.com/ollama/ollama-python

### 配置和使用Ollama与DeepSeek R1 #### 安装依赖库 为了能够在Python环境中顺利操作Ollama及其托管的DeepSeek R1模型,需先确保已安装必要的Python包。通常情况下,`requests`库用于HTTP请求交互,而`json`模块处理数据交换。 ```bash pip install requests ``` #### 初始化Ollama客户端 创建一个简单的Python脚本来初始化连接到本地或远程Ollama服务器的会话。假设Ollama服务已经在本地启动并监听默认端口: ```python import requests def init_ollama_session(host='http://localhost', port=8080): base_url = f"{host}:{port}" session = requests.Session() return session, base_url ``` #### 加载DeepSeek R1模型 加载指定名称的预训练模型实例,这里特指名为`deepseek-r1`的大规模语言模型。此过程涉及向特定API路径发送GET请求来获取模型元信息,并确认其可用状态。 ```python session, url_prefix = init_ollama_session() model_name = "deepseek-r1" response = session.get(f'{url_prefix}/models/{model_name}') if response.status_code == 200: model_info = response.json() print(f'Model {model_name} loaded successfully.') else: raise Exception('Failed to load the specified model') ``` #### 发送查询请求至DeepSeek R1 构建函数封装对话逻辑,允许用户输入问题并通过POST方法提交给目标URL地址。返回的结果经过解析后呈现给人类可读的形式。 ```python def query_deepseek_r1(question_text, max_tokens=50): payload = { 'prompt': question_text, 'max_tokens': max_tokens } endpoint = '/generate' resp = session.post( f'{url_prefix}{endpoint}', json=payload ) result = resp.json().get('choices')[0].get('text').strip() if resp.ok else None return result or "Error occurred during processing." ``` #### 实际应用案例展示 下面给出一段完整的代码片段作为例子,演示如何利用上述定义的功能完成一次基本交流互动。 ```python if __name__ == '__main__': try: sess, _ = init_ollama_session() user_input = input("Please enter your question here:\n") answer = query_deepseek_r1(user_input) print("\nThe AI responds:") print(answer) except KeyboardInterrupt: print('\nSession interrupted by user.') finally: sess.close() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值