在 Python 中使用 Ollama API

文章目录

  • 一、环境准备
  • 二、使用方法
  • 1.简单对话
  • 2.流式响应
  • 3.结构化输出
  • 4.自定义客户端
  • 4.1 同步客户端
  • 4.2 异步客户端
  • 4.3 同步 & 异步客户端不同调用次数耗时对比测试
  • 三、常用的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

    作者:AllYoung_362

    物联沃分享整理
    物联沃-IOTWORD物联网 » 在 Python 中使用 Ollama API

    发表回复