当前位置: 首页 > news >正文

6、使用one-api管理统一管理大模型,并开始使用本地大模型

文章目录

  • 本节内容介绍
  • 集中接入:将大模型统一管理起来
    • 当使用了大模型代理
    • 大模型代理示例
  • 开源模型:如何使用Hugging Face上的模型
    • modelscope
    • 使用 pipeline 调用模型
    • 用底层实现调用模型
    • 流式输出
  • 如何在项目中使用开源模型
    • 使用 LangChain
    • 使用集中接入
    • 开始使用ollama

本节内容介绍

在本节中,我们一起来使用one-api来模拟openai,给应用提供对应的sk;并尝试使用各种方式来使用本地的大模型,尤其是最近deepseek爆火,你更需要学习使用ollama上面提供的多个deepseek模型了

集中接入:将大模型统一管理起来

集中接入,就是把大模型的接入统一到一个地方管理起来,下面这张图可以很好地帮我们理解集中接入:

在这里插入图片描述

从这个图上,你已经看出来了,所谓的集中接入,其实就是构建了一个代理,我们后面就称它为大模型代理。

到这里,你可能产生这样的疑问:我直接用大模型不好吗?为什么还要在中间加上一层代理呢?

集中接入是一种架构上的调整,顾名思义,我需要是一个服务,才会有架构调整的说法。如果只是像前面几讲,如果在本地就可以运行起来的一些程序,确实没有必要在中间加入一层。但在真实的项目中,我们往往是要构建一个服务,这时集中接入的价值就体现出来了。

之所以要有一个中间层,最直接的一个问题就是限流问题。大模型服务本身资源消耗很大,提供大模型服务的供应商为了保证尽可能多的用户享受到正常的服务,所以,它对单用户实施了限流。以 OpenAI API 为例,下面就是它的限流标准,其中 RPM 是 requests per minute(每分钟请求数),TPM 是 tokens per minute(每分钟 Token 数)。

如果我们是一个人或是规模比较小的服务,这个限流标准大概是够用的,但如果我们要对外提供服务,这个标准大概率是不够用的。解决这个问题最简单的办法就是多申请一些账号,形成一个号池,这样限流标准对我们来说就大幅度提高了,但随之而来的一个问题就是如何管理号池。

稍微仔细想一下,你就会发现,实现一个还不错的号池管理还是比较麻烦的。比如,按什么方式在不同的账号之间进行选择,怎样管理失效的账号等等。真的要实现好一个号池,就等于实现了一个完整的运维工具,可是,你的应用目标是做一个 AI 应用。与其自己实现这么一套完整的功能,还不如用已有的工具来完成这个目标。是的,已经有一些现成的工具可以完成这个目标。

当使用了大模型代理

在介绍具体的工具之前,我们先来看看如果把接入管理独立出来之后,会产生怎样的变化。

首先肯定是解决了多账号管理的问题。所有的账号都配置在这个代理上,而对于我们自己的应用而言,只配置一个账号就好。这个大模型代理通常会采用 OpenAI 兼容的 API,也就是说,你完全可以用 OpenAI API 的使用方式使用它,一般来说,我们只要替换一下 API_BASE 和 API_KEY,而其它的代码可以完全保持不变。这也是我们代理能够平滑接入的原因。

有了大模型代理之后,我们还可以有一些其它的变化。一个典型的应用场景就是接入不同的供应商。虽然我们一直在讲 OpenAI API,但由于众所周知的原因,我们并不能直接访问 OpenAI API。

一个常见的解决办法是,通过一些供应商来进行访问。一般来说,我们并不会依赖于一家供应商,所以,配置多个供应商也是很常见的。有了大模型代理之后,这些复杂性就从我们的应用中剥离出去了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不同的供应商上提供的 API 可能会有所差异。比如,微软的 Azure 也提供了 OpenAI 的服务,但接口略有差异。如果是自己的代码,我们就需要自己管理这种差异。有了大模型代理,我们就可以把这种复杂性交给代理,而让我们的代码采用统一的接口进行访问。

前面讨论的还都是 OpenAI 的模型。既然有了大模型代理,我们完全可以再进一步,通过它访问不同的模型。事实上,很多供应商就提供了类似的能力,比如 OpenRouter 就提供了许多不同模型的访问能力,而它们都是基于 OpenAI 兼容接口的。通过大模型代理,我们也可以访问不同的大模型。

不仅仅是使用别人的服务,我们甚至可以访问自己本地部署的大模型。后面我们讲到本地部署大模型时,我们会谈到如何利用大模型代理访问本地大模型。

总之,有了大模型代理之后,各种接入问题的复杂度就完全交给它了。在应用端来看,接入就完全简化成一个 OpenAI 的接入接口。这也是我们前面重点介绍 OpenAI API 接口的原因。另外,我们前面说过,LangChain 在一些场景下是不适用的,其中的一个原因就是它提供的一些抽象在某些情况下是失效的。有了大模型代理,LangChain 提供的模型抽象就显得没有必要了。

好了,现在你已经了解大模型代理在我们的应用中扮演的角色,下面我们就来看如何使用搭建一个大模型代理。

大模型代理示例

能够提供大模型代理的工具有很多,下面我以 One-API 为例介绍一下基本的用法。One-API 就是一个典型的大模型代理,它提供了以 OpenAI API 接口访问各种大模型的能力。我们常见的一些大模型在 One-API 中都得到了支持,比如,GPT、Claude、文心一言、通义千问等等。它在行业内得到了很广泛地使用,所以,它在能力上也得到了很多扩展,比如,计费管理、渠道管理等等。

安装 One-API 最简单的方式是使用 Docker,比如:

docker run --name one-api -d --restart always -p 3000:3000 -e SQL_DSN="root:123456741852q@+@tcp(101.42.44.178:2881)/oneapi" -e TZ=Asia/Shanghai -v /home/zeng/soft/data/one-api:/data justsong/one-api

在实际使用中,我们会根据自己的实际情况修改数据库配置(SQL_DSN),如果配置了 SQL_DSN,One-API 会使用 MySQL 作为数据库。此外需要调整的配置就是映射目录,这个目录里存放的是数据和日志:

-v /home/zeng/soft/data/one-api:/data

启动之后,访问对应的地址,比如,在本地启动就是访问 http://localhost:3000/,你就会看到它的界面。要想看到更多的配置项,需要进行登录。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这里面的重点是渠道,这对应的就是我们前面提到的服务供应商。我们可以添加新的渠道(使用root/123456登录后才可配置渠道),这里主要的几个选项是:

  • 类型:它决定了在转发过程中采用什么 API 接入到后端的模型上,比如,OpenAI 就会采用 OpenAI API。
  • 模型:这个渠道支持的模型,比如,gpt-4o-mini。每个渠道可以配置很多的模型。
  • 连接信息:接入地址(代理)和 API Key(密钥),如果是同一个供应商的多个账号,可以采用批量创建的方式,输入多个 API Key。

在这里插入图片描述

在这个配置里,有一个比较有意思的配置是模型重定向,就是把一个模型名称转换成另外一个模型的名称。一种典型的用法是,把一个比较昂贵的模型用另外一个便宜的模型代替。比如,早期的 GPT-4 价格是很高的,而后期的 GPT-4o 价格就要便宜不少,而且性能会更强大。我们就可以在这里做一个映射,让应用请求过来的 GPT 4,而真正请求到后端都是 GPT-4o。

还有一种用法是,给模型起一个新名称。这样一来,我们的应用提供给用户的是一个自定义的名称,请求到代理上之后,再转成真正的模型发出去,以此屏蔽掉后端真正的模型。我们在不少应用上见到的所谓自己的模型,都可以这么实现出来。

如果配置了多个渠道之后,我们可以在渠道列表看到后面截图里的选项。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这里我们可以做一些运维类的工作,比如,禁用失效的渠道。还有一个点是优先级,它是用来确定访问顺序的。比如,多个渠道都提供了 gpt-4o-mini 这个模型,我们会访问优先级高的渠道。

设置了模型之后,我们还需要添加 API Key,也就是这里的令牌。我们可以根据自己的需要设置相应的权限。

在这里插入图片描述

具体的 API Key 是自动生成的。我们创建好令牌之后,可以在令牌列表中找到。只要在这里复制就可以得到所需的 API Key 了。

在这里插入图片描述

后面的操作我们都很熟悉了,就是把 One API 的访问地址和 API Key 配置到我们的代码里,和平时使用 OpenAI API 是一样的。

这里只讲了 One API 最基本的用法。这个工具已经开发了一段时间,功能还是比较多的,比如,可以设置访问失败时自动禁用渠道,出现问题时通知运维人员等等。你如果有需要可以去更多的探索。

开源模型:如何使用Hugging Face上的模型

在传统开发中,如果为这些企业服务,一个重要的议题就是私有化部署,但像 OpenAI 这样的服务显然是无法满足私有化部署的需求。在这种情况下,一个能够运行在本地的大模型就显得至关重要了,之所以我们可以在本地运行模型,是因为有人把已经做好的模型开放了出来,这就是开源的力量。

modelscope

如今的 Hugging Face 主要除了可以分享模型(model),还可以分享数据集(dataset),还有部署起来的应用(Space)。模型也不止是语言模型,而是其它各式各样的模型,比如图像生成模型、语音生成模型等等。为了让用户更好地使用其服务,Hugging Face 还提供了很多的工具,比如简化模型使用的 transformers 程序库、简化 AI 应用开发和部署的 Gradio 等等。

modelscope号称国内的Hugging Face,由于网络限制,所以下面都是使用modelscope作为示例

使用 pipeline 调用模型

调用 modelscope 模型有两种方式:高层接口和底层接口。高层接口相当于是对底层接口做了封装,让代码使用起来更容易,相对而言,底层接口则有更大的灵活性。在高层接口里,我们核心要知道的一个概念就是管道(pipeline)。和软件领域所有叫管道的概念一样,它要做的就是一步一步地进行处理,一个阶段完成之后,交给下一个阶段,我们来看一个例子:

# 首先使用命令将模型下载到本地:
# modelscope download --model Qwen/Qwen2.5-3B-Instruct --local_dir ./Qwen2.5-3B-Instructimport torch
from transformers import pipelinedevice = "cuda" if torch.cuda.is_available() else "cpu"messages = [{"role": "user", "content": "请写一首赞美秋天的五言绝句"},
]
# 使用本地的
pipe = pipeline("text-generation", model="/home/zeng/llm/model/Qwen2.5-3B-Instruct", device=device, max_new_tokens=100)
result = pipe(messages)
print(result[-1]['generated_text'][-1]['content'])

这段代码的核心就是这两句:

pipe = pipeline("text-generation", model="/home/zeng/llm/model/Qwen2.5-3B-Instruct", device=device,
result = pipe(messages)

先构建了一个管道,第一个参数指定了它的用途,这里是文本生成(text-generation), pipeline 会根据不同的用途进行不同的管道配置。第二个参数是模型,在这个例子里面,我们使用的模型是阿里的通义千问(Qwen),引用模型的方式就是“用户名 / 模型名”,在这里就是“Qwen/Qwen2.5-3B-Instruct”。

构建好了管道,就可以调用模型了,我们把消息传给模型,它就会给我们产生一个结果。下面是我一次执行的结果:

秋风送爽至,落叶铺金地。
丰收稻谷香,丰收喜悦起。

前面说了,pipeline 模型的第一个参数指定了用途。除了像大模型做文本生成,modelscope 提供了大量的不同模型,可以帮助我们完成其它的工作。具体请到modelscope模型库观看:https://www.modelscope.cn/models

用底层实现调用模型

前面我们已经了解了管道的概念,对高层接口有了基本的了解。不过,管道封装起来的流程是什么样的呢?这就需要我们了解一下底层实现。

下面就是一个使用底层的实现,它实现的功能与上一段代码完全一样,理解了它的实现,你就基本上知道 pipeline 是怎样实现的了。

from transformers import AutoTokenizer, AutoModelForCausalLMtokenizer = AutoTokenizer.from_pretrained("/home/zeng/llm/model/Qwen2.5-3B-Instruct")
model = AutoModelForCausalLM.from_pretrained("/home/zeng/llm/model/Qwen2.5-3B-Instruct")messages = [{"role": "user", "content": "请写一首赞美春天的诗,要求不包含春字"},
]text = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)generated_ids = model.generate(**model_inputs,max_new_tokens=512
)
generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(response)

从代码上看,它的流程复杂多了。但实际上,只要我们理解了大模型的处理过程,这段代码就很容易理解了。这个过程的核心就是三步。

第一步,把输入转换成 Token。

text = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)

第二步,大模型根据输入生成相应的内容。

generated_ids = model.generate(**model_inputs,max_new_tokens=512
)

第三步,生成的结果是 Token,还需要把它转成文本。

generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]

基本上就是这样一个过程。因为过程中涉及到了 Token 和文本之间的转换,所以,这里还有一个 Tokenizer,它就是负责转换的模型。一般来说,大模型都要和对应的 Tokenizer 一起使用,所以,你会看到它俩往往给出的是同一个模型名字:

tokenizer = AutoTokenizer.from_pretrained("/home/zeng/llm/model/Qwen2.5-3B-Instruct")
model = AutoModelForCausalLM.from_pretrained("/home/zeng/llm/model/Qwen2.5-3B-Instruct")

流式输出

前面实现的功能都是由大模型一次性生成的。在聊天模式下,我们还需要使用流式输出。在 Hugging Face 的 API 里,我们可以使用 Streamer 来实现这一点,从名字上就可以知道,它是用来处理流式输出的。下面就是一个演示了流式输出的例子:

from transformers import AutoTokenizer, AutoModelForCausalLM, TextStreamertokenizer = AutoTokenizer.from_pretrained("/home/zeng/llm/model/Qwen2.5-3B-Instruct")
model = AutoModelForCausalLM.from_pretrained("/home/zeng/llm/model/Qwen2.5-3B-Instruct")messages = [{"role": "user", "content": "请写一首赞美秋天的五言绝句"},
]text = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
generated_ids = model.generate(**model_inputs,max_new_tokens=512,streamer=streamer,
)

在这个例子里,我们用到了 TextStreamer,它会直接把生成结果输出到控制台上。如果我们要实现一个控制台应用,它是可以用的。但更多的情况下,我们需要拿到输出结果,再去做相应的处理,比如,服务端把生成的内容发送给客户端。这种情况下,我们可以使用 TextIteratorStreamer,下面是一个例子:

from transformers import AutoTokenizer, AutoModelForCausalLM, TextStreamer, TextIteratorStreamer
from threading import Threadtokenizer = AutoTokenizer.from_pretrained("/home/zeng/llm/model/Qwen2.5-3B-Instruct")
model = AutoModelForCausalLM.from_pretrained("/home/zeng/llm/model/Qwen2.5-3B-Instruct")messages = [{"role": "user", "content": "请写一首赞美秋天的五言绝句"},
]text = tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)
streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
generation_kwargs = dict(model_inputs, streamer=streamer, max_new_tokens=20)
thread = Thread(target=model.generate, kwargs=generation_kwargs)
thread.start()for text in streamer:print(text)

与之前最大的不同是,这段代码启用了多线程,这样一来,生成和输出是异步处理的,不会彼此阻塞,更符合真实代码中的处理。正如 TextIteratorStreamer 这个名字所显示的,它实现了 Iterator,所以,我们可以在其上进行迭代。

有了对 Streamer 的理解,我们就可以回到 pipeline 上,给 pipeline 增加流式输出的能力:

import torch
from transformers import pipeline, TextIteratorStreamerdevice = "cuda" if torch.cuda.is_available() else "cpu"messages = [{"role": "user", "content": "请写一首赞美秋天的五言绝句"},
]pipe = pipeline("text-generation", model="/home/zeng/llm/model/Qwen2.5-3B-Instruct", device=device, max_new_tokens=100)streamer = TextIteratorStreamer(pipe.tokenizer, skip_prompt=True, skip_special_tokens=True)generation_kwargs = dict(text_inputs=messages, streamer=streamer)
thread = Thread(target=pipe, kwargs=generation_kwargs)
thread.start()for text in streamer:print(text)

至此,我们对如何调用 Hugging Face 上的模型有了一个初步的了解,有了这个基础,下面我们来看看如何在项目中使用这些模型。

如何在项目中使用开源模型

前面我们讲了如何使用 Hugging Face 上的开源模型。这一讲,我们看看如何在实际的项目中使用这些模型。

这一讲,我们就来谈谈两种常见的封装:使用 LangChain 和使用集中接入。

使用 LangChain

LangChain 的模型就是 LangChain 给我们提供的一层封装,屏蔽掉了不同大模型之间的差异,让我们可以方便地在不同大模型之间进行切换。任何想要接入 LangChain 体系的大模型,只要实现了相应的接口,就可以无缝地嵌入到 LangChain 的体系中去,Hugging Face 的模型就是这么做的。

我们之所以要把 Hugging Face 模型嵌入到 LangChain 的体系中,主要是因为我们希望使用 LangChain 提供的其它抽象。

要使用 Hugging Face 相关的代码,首先需要安装相应的包:

pip install langchain-huggingface

langchain-huggingface 是 Hugging Face 和 LangChain 共同维护的一个包,其目标是缩短将 Hugging Face 生态的新功能带给 LangChain 用户的时间。它里面包含了很多功能:

  • 有各种模型的实现,比如聊天模型和 Embedding 模型;
  • 有数据集的实现,它实现成了 DocumentLoader;
  • 有工具的实现,比如文本分类、文本转语音等。

从提供的内容上来看,这个包封装了 Hugging Face 上的主要能力——模型和数据集。其中,不同的模型因为能力上的差异做了不同归结:属于大语言模型的,就归结到了 LangChain 模型上,而无法归结的,就以工具的形式提供。

有了最基本的了解,我们来实现一个简单的功能:

import torch
from langchain_huggingface import HuggingFacePipeline, ChatHuggingFacedevice = 0 if torch.cuda.is_available() else -1llm = HuggingFacePipeline.from_model_id(model_id="/home/zeng/llm/model/Qwen2.5-3B-Instruct",task="text-generation",device=device,pipeline_kwargs=dict(max_new_tokens=512,return_full_text=False,),
)chat_model = ChatHuggingFace(llm=llm)result = chat_model.invoke("写一首赞美秋天的五言绝句。")
print(result.content)

这里我们也是先构建了一个管道,通过上一讲的学习,这个构建管道的过程我们其实并不陌生,无非就是设定模型 ID、模型用途(task)以及其它一些配置参数。虽然从命名上看,我们是在构建一个管道,但这里的 HuggingFacePipeline 是一个 LangChain 的 LLM 类型。

有了 HuggingFacePipeline,我们再把它转成一个 ChatModel,实际上就是做了一层封装:

chat_model = ChatHuggingFace(llm=llm)

ChatModel 我们之前已经谈了很多,有了 ChatModel,接下来它就可以与我们熟悉的那些 LangChain 抽象配合在一起了。在我们的示例里,我们就是直接调用它。

result = chat_model.invoke("写一首赞美秋天的五言绝句。")
print(result.content)

前面我们说过,在 LangChain 的体系下,有 ChatModel 和 LLM 两种抽象都可以处理大模型。我们这里定义出的 HuggingFacePipeline 就是 LLM,它也完全可以拿过来单独使用。

llm.invoke("写一首赞美秋天的五言绝句。")

在我写下这段文字的时候,langchain-huggingface 这个包的发布时间并不算很长,实现上还有一些不够完善的地方。比如,ChatHuggingFace 的流式应答支持得就不算特别好。在 langchain-community 这个包里,还有一个旧版的 ChatHuggingFace,它本身提供了流的支持,只不过,它需要与旧的一套代码配合使用,而这套代码都处于被舍弃的状态(Deprecated)。

虽然我们可以在代码中支持不同模型的封装,但其实我们还有另外一种选择,就是采用集中接入的方案,彻底摆脱在代码中集成模型。

使用集中接入

我们继续以一开始的 One-API 为例。在创建新渠道的时候,类型是有很多选项的,它决定着后端会接入到哪个供应商的模型上。其中的一个选项是 Ollama:

在这里插入图片描述

ollama是一个可以在本地运行大模型的轻量级框架。同我们在本地运行代码访问大模型类似,它可以在本地启动一个服务,我们可以通过这个服务去使用相应的大模型。类似的东西也有不少,比如 vllm、gpt4all 等。

有一个运行在本地的大模型,我们就可以做很多的事情了。比如,搭建一个属于自己的聊天机器人,尝试不同的大模型,还有一些新的 AI 编码工具,也是可以接入到本地的大模型。单纯从一个用户的角度,我也推荐每个程序员尝试着在本地运行大模型,做一些不同的事情,它会加深你对大模型的理解。

开始使用ollama

下面我就以 Ollama 为例,介绍一下基本的用法。安装 Ollama 只要找到对应的安装包即可,如果是 Linux,我们可以通过命令行进行安装:

curl -fsSL https://ollama.com/install.sh | sh

理解 Ollama 的使用,可以类比于 Docker,所以,在 Ollama 的命令中,我们会看到 pull、push、run 等命令。要想使用大模型,我们首先要把大模型拉到本地:

ollama pull qwen2.5

同一个模型会有多个不同的版本,比如,通义千问 2.5 就有 0.5B、1.5B、3B、7B、14B、32B、72B 等不同规模的版本。即便是同一个规模,还会有不同配置的版本。在 Ollama 中,这些不同的版本是通过 Tag 区分的,比如,如果我们想使用 0.5B 版本的,可以这样拉取。

ollama pull qwen2.5:0.5b

如果想做一些简单的测试,我们可以直接在本地把它运行起来。

ollama run qwen2.5

启动之后,就是一个命令行版的对话框,对于程序员来说,这就比较熟悉了。

>>> 写一首诗
春风吹绿江南岸,芳草萋萋野花开。
千帆过尽江心月,独坐闲庭听流水。风送花香满庭院,鸟语花香醉晚晴。
时光荏苒如白驹,岁月静好待人来。

启动 Ollama 实际上是启动了一个服务,所以,我们也可以通过 API 访问这个服务。Ollama 提供了两类 API,一类是它自身定义的 API,另一类就是 OpenAI 兼容 API。下面就是通过它自身 API 访问服务的示例。

curl http://127.0.0.1:11434/api/chat -d '{"model": "qwen2.5","messages": [{"model": "qwen2.5","prompt": "写一首关于AI的诗"}]
}'

我们可以通过 list 命令查看已经安装的模型。

ollama listNAME                                               ID              SIZE      MODIFIED
qwen2.5:0.5b                                       a8b0c5157701    397 MB    16 hours ago
qwen2.5-coder:32b                                  4bd6cbf2d094    19 GB     2 days ago
qwen2.5:latest                                     845dbda0ea48    4.7 GB    7 days ago
llama3.2:latest                                    a80c4f17acd5    2.0 GB    8 days ago

在 One API 中填写的就是这里的 NAME 字段,比如,我们在配置中添加了 qwen2.5:0.5b。配置好之后,我们就可以在代码中直接指定模型名为 qwen2.5:0.5b。

completion = client.chat.completions.create(model="qwen2.5:0.5b",messages=self.messages,temperature=0
)

你看到了,这里我们用到 OpenAI 的程序库,但我在这里指定的模型是 qwen2.5:0.5b,并不是 OpenAI 提供的模型。这也是我们集中接入采用 OpenAI 兼容 API 的意义所在。我们在代码层面上,不用考虑模型的差异,因为集中接入层做了这层封装,把不同的供应商屏蔽了,从而保证了我们代码的稳定性。

顺便说一下,Ollama 本身也提供了一个程序库,LangChain 也提供了 Ollama 的封装。如果有需要,可以自行查看

细心的同学可能发现了,我们在讨论 Ollama 的过程中,并没有提到 Hugging Face。Ollama 相当于本身提供了一个仓库,我们是从 Ollama 的仓库里拉取的模型。但说到模型的丰富程度,肯定是 Hugging Face 更胜一筹的。我们可以使用 Hugging Face 的模型吗?答案是可以。

在 Ollama 上使用模型,运行的命令是后面这样。

ollama run hf.co/{username}/{repository}

不过,有一点要说明一下,并不是所有的模型都可以使用 Ollama 运行的。为了确认这一点,你可以在模型的说明页上查看一下。点击 “Use this model”,如果下拉菜单中有 Ollama,那就是可以使用,你可以复制相应的命令去执行;否则,这个模型可能无法直接使用。

相关文章:

6、使用one-api管理统一管理大模型,并开始使用本地大模型

文章目录 本节内容介绍集中接入:将大模型统一管理起来当使用了大模型代理大模型代理示例 开源模型:如何使用Hugging Face上的模型modelscope使用 pipeline 调用模型用底层实现调用模型流式输出 如何在项目中使用开源模型使用 LangChain使用集中接入开始使…...

DFS+回溯+剪枝(深度优先搜索)——搜索算法

DFS也就是深度优先搜索,比如二叉树的前,中,后序遍历都属于DFS。其本质是递归,要学好DFS首先需要掌握递归。接下来咱们就一起来学习DFS涉及的算法。 一、递归 1.什么是递归? 递归可以这样理解把它拆分出来&#xff0…...

【数据结构】_堆的实现

目录 1. 堆的实现 1.1 Heap.h 1.2 Heap.c 1.3 Test_Heap.c 专栏前文中,已经介绍了入堆及向上调整算法,出堆及向下调整算法,详情见下文: 【数据结构】_堆的结构及向上、向下调整算法-CSDN博客文章浏览阅读352次,点…...

读书笔记《左耳听风》

读书笔记《左耳听风》 从今年开始,打算给自己定一下在看完书后整理成博客的计划。以往很多看完的书仅仅停留在看完,再回顾的时候总感觉已经不甚清晰了,希望能坚持下去。 《左耳听风》是今年我看完的第一本书,内容针对的是程序员…...

Axure原型图怎么通过链接共享

一、进入Axure 二、点击共享 三、弹出下面弹框,点击发布就可以了 发布成功后,会展示链接,复制即可共享给他人 四、发布失败可能的原因 Axure未更新,首页菜单栏点击帮助选择Axure更新,完成更新重复以上步骤即可...

本地部署DeepSeek,并使用UI界面进行快速交互

一.需要本地部署的原因 1.我们在deepseek的官网界面进行交互时,经常会出现如下问题,不能正常交互,很是困扰: 2.本地部署的好处 就是能够很流畅的与deepseek进行交互;也有缺点,现在官网交互的版本更高一点…...

ESP32S3读取数字麦克风INMP441的音频数据

ESP32S3 与 INMP441 麦克风模块的集成通常涉及使用 I2S 接口进行数字音频数据的传输。INMP441 是一款高性能的数字麦克风,它通过 I2S 接口输出音频数据。在 Arduino 环境中,ESP32S3 的开发通常使用 ESP-IDF(Espressif IoT Development Framew…...

移动(新)魔百盒刷机教程[M301A_YS]

刚刚成功刷了一个坏的魔百盒,简单记录一下。 刷电视盒子有两种:卡刷和线刷。 线刷 一、线刷准备 1.刷机工具 Amlogic USB Burning Tool 晶晨线刷烧录工具 2.固件 根据盒子的型号、代工等找到对应的固件 二、线刷步骤 电脑打开下好的 Amlogic US…...

15 大 AWS 服务

在不断发展的云计算世界中,Amazon Web Services (AWS) 已成为一股主导力量,提供许多服务以满足各种应用程序开发、部署和管理方面的需求。本文将探讨 15 项 AWS 服务。这些服务对于构建可扩展、可靠且高效的系统至关重要。 1.Amazon EC2(弹性…...

【C++】命名空间

🌟 Hello,我是egoist2023! 🌍 种一棵树最好是十年前,其次是现在! 目录 背景知识 命名空间(namespace) 为何引入namespace namespace的定义 namespace的使用 背景知识 C的起源要追溯到1979年&#xff0…...

项目实战(11)-双通道气体压力计V1.0

一. 产品简介: 1、项目背景是在实际应用中需要监控通道内气体的压力,压力计分为两个通道;通道一时实时监控;通道二是保压,设定保压值得上下限后通道内得气体压力值会一直保持在这个范围内。 二. 应用场景&#xff1a…...

python+unity落地方案实现AI 换脸融合

先上效果再说技术结论,使用的是自行搭建的AI人脸融合库,可以离线不受限制无限次生成,有需要的可以后台私信python ai换脸融合。 TODO 未来的方向:3D人脸融合和AI数据训练 这个技术使用的是openvcinsighface,openvc…...

开启对话式智能分析新纪元——Wyn商业智能 BI 携手Deepseek 驱动数据分析变革

2月18号,Wyn 商业智能 V8.0Update1 版本将重磅推出对话式智能分析,集成Deepseek R1大模型,通过AI技术的深度融合,致力于打造"会思考的BI系统",让数据价值触手可及,助力企业实现从数据洞察到决策执…...

数据结构——【二叉树模版】

#思路 1、二叉树不同于数的构建,在树节点类中,有数据,左子结点,右子节点三个属性,在树类的构造函数中,添加了变量maxNodes,用于后续列表索引的判断 2.GetTreeNode()函数是常用方法,…...

DeepSeek之于心理学的一点思考

模型和硬件参数对应关系参考 模型参数规模 典型用途 CPU建议 GPU建议 最小内存建议 磁盘空间建议 适用场景 1.5b(15亿) 小型推理、轻量级任务 4核以上(Intel i5/AMD Ryzen5) 可选,入门级GPU(如NVIDIA GTX1650 4GB显存) 8GB 10GB以上SSD 小型NLP任务、文…...

mysql 存储过程和自定义函数 详解

首先创建存储过程或者自定义函数时,都要使用use database 切换到目标数据库,因为存储过程和自定义函数都是属于某个数据库的。 存储过程是一种预编译的 SQL 代码集合,封装在数据库对象中。以下是一些常见的存储过程的关键字: 存…...

数据结构:单链表

1.概念: 单链表(Singly Linked List)是一种常见的数据结构,它由一系列节点(Node)组成,每个节点包含两个部分: 数据域(Data):存储节点的值或数据。…...

部署项目(ubantu服务器,配置jdk,启动项目,及测试)

目录 1、ubantu安装jdk 2、部署项目 ​ 解决 java -jar 报错:xxx.jar 中没有主清单属性 ​ 3、测试 4、查看系统部署的应用 1、ubantu安装jdk #压缩文件jdk文件:tar -czvf jdk17.tar.gz jdk17 #解压jdk文件:tar -xzvf jdk17.tar.gz 参…...

deepseek本地部署教程

第一步:进入Ollama官网 (Download Ollama on macOS),下载ollama(注意需要Window10或更高的版本),安装(OllamaSetup.exe),默认在c盘 第二步:点击Models,再点击…...

MySQL主从同步+binlog

一、简介 MySQL内建的复制功能是构建大型,高性能应用程序的基础 通过将MySQL的某一台主机(master)的数据复制到其他主机(slaves)上,并重新执行一遍来执行 复制过程中一台服务器充当主服务器,而…...

防火墙术语大全( Firewalld Glossary of Terms)

防火墙术语大全 防火墙作为网络安全中不可或缺的设备,在各种网络架构中扮演着至关重要的角色。无论是企业级防火墙、云防火墙还是家用路由器内置的防火墙,它们的工作原理和配置策略都离不开一系列专业术语的支撑。对于网络工程师来说,掌握这…...

LeetCode刷题---数组---697

数组的度 697. 数组的度 - 力扣(LeetCode) 题目: 给定一个非空且只包含非负数的整数数组 nums,数组的 度 的定义是指数组里任一元素出现频数的最大值。 你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组&am…...

C语言基础08:运算符+流程控制总结

运算符 算术运算符 结果:数值 、-、*、\、%、(正)、-(负)、、-- i和i 相同点:i自身都会增1 不同点:它们运算的最终结果是不同的。i:先使用,后计算;i&am…...

[安装FlashAttention] CUDA版本 和 Nvidia驱动版本

nvidia-smi 查看driver api 的CUDA版本 听说这个是本机能装到的最高版本 那这样看来我最高能装到12.4。 nvcc -V 查看当前runtime api的CUDA版本 还是古老的11.5版本,没办法啊,FlashAttention老是说不支持? 安装Torch时选择的CUDA版本 p…...

Android图片加载框架Coil,Kotlin

Android图片加载框架Coil,Kotlin implementation("io.coil-kt:coil:1.4.0") import android.os.Bundle import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import coil.Coil i…...

Win11下搭建Kafka环境

目录 一、环境准备 二、安装JDK 1、下载JDK 2、配置环境变量 3、验证 三、安装zookeeper 1、下载Zookeeper安装包 2、配置环境变量 3、修改配置文件zoo.cfg 4、启动Zookeeper服务 4.1 启动Zookeeper客户端验证 4.2 启动客户端 四、安装Kafka 1、下载Kafka安装包…...

从大规模恶意攻击 DeepSeek 事件看 AI 创新隐忧:安全可观测体系建设刻不容缓

作者:羿莉(萧羿) 全球出圈的中国大模型 DeepSeek 作为一款革命性的大型语言模型,以其卓越的自然语言处理能力和创新性成本控制引领行业前沿。该模型不仅在性能上媲美 OpenAI-o1,而且在推理模型的成本优化上实现了突破…...

模拟(典型算法思想)—— OJ例题算法解析思路

目录 一、1576. 替换所有的问号 - 力扣(LeetCode) 运行代码: 1. 输入和输出 2. 变量初始化 3. 遍历字符串 4. 替换逻辑 5. 返回结果 整体分析 1. 思路总结 2. 为什么要这样设计 3. 时间复杂度与空间复杂度 4. 边界情况 二、495. 提莫攻击 - 力扣(LeetCode) …...

pgsql最快的数据导入BeginBinaryImport

PostgreSQL 的 BeginBinaryImport 是 libpq(PostgreSQL 的 C 语言客户端库) 中的一个函数,用于高效实现二进制数据的大批量导入。以下是详细介绍及适用语言说明: BeginBinaryImport 的作用 功能 它是 PostgreSQL C 接口库&#xf…...

【进程与线程】如何编写一个守护进程

如何编写一个守护进程。我们首先需要理解守护进程是什么。守护进程是在后台运行的进程,通常没有控制终端,用于执行系统任务,比如服务器或者定时任务。 用户可能想创建一个长期运行的服务,比如Web服务器或者日志监控程序。 首先&a…...

Docker容器访问外网:启动时的网络参数配置指南

在启动Docker镜像时,可以通过设置网络参数来确保容器能够访问外网。以下是几种常见的方法: 1. 使用默认的bridge网络 Docker的默认网络模式是bridge,它会创建一个虚拟网桥,将容器连接到宿主机的网络上。在大多数情况下,使用默认的bridge网络配置即可使容器访问外网。 启动…...

大数据-259 离线数仓 - Griffin架构 修改配置 pom.xml sparkProperties 编译启动

点一下关注吧!!!非常感谢!!持续更新!!! Java篇开始了! 目前开始更新 MyBatis,一起深入浅出! 目前已经更新到了: Hadoop&#xff0…...

DeepSeek神经网络:技术架构与实现原理探析

以下是一篇关于DeepSeek神经网络的研究及实现原理的综述性文章,结合其技术架构、训练范式及创新点展开分析: 1. 核心架构设计 DeepSeek的神经网络架构以**混合专家模型(Mixture of Experts, MOE)**为基础,结合轻量化…...

KTOR:高效的Linux横向移动与无文件落地HTTP服务扫描工具

地址:https://github.com/MartinxMax/KTOR 简介 KTOR 是一款专为 Linux 横向渗透设计的工具。通过该工具,您可以快速扫描内部 HTTP 服务,以便进一步进行网络渗透,且实现无文件落地扫描。 在CTF中通常需要利用本地其他端口HTTP服务或其他主…...

C++ Primer 类型转换

欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…...

2025新的一年网络营销推广该怎么干?

2025年,全球网民数量预计突破60亿,但流量红利消退、用户注意力稀缺、技术迭代加速……企业网络营销正面临前所未有的“生存战”。如何在竞争中突围?小马识途营销机构基于十五年实战经验,总结出2025年企业必须抢占的五大核心战场&a…...

java实现Http请求方式的几种常见方式

背景 在实际开发过程中,我们经常需要调用对方提供的接口或测试自己写的接口是否合适。很多项目都会封装规定好本身项目的接口规范,所以大多数需要去调用对方提供的接口或第三方接口(短信、天气等)。若是普通java工程推荐使用OkHt…...

安卓开发,底部导航栏

1、创建导航栏图标 使用系统自带的矢量图库文件,鼠标右键点击res->New->Vector Asset 修改 Name , Clip art 和 Color 再创建一个 同样的方法再创建四个按钮 2、添加百分比布局依赖 app\build.gradle.kts 中添加百分比布局依赖,并点击Sync Now …...

Spring Boot中实现多租户架构

文章目录 Spring Boot中实现多租户架构多租户架构概述核心思想多租户的三种模式优势挑战租户识别机制1. 租户标识(Tenant Identifier)2. 常见的租户识别方式3. 实现租户识别的关键点4. 租户识别示例代码5. 租户识别机制的挑战数据库隔离的实现1. 数据库隔离的核心目标2. 数据…...

SpringBoot源码解析(十):应用上下文AnnotationConfigServletWebServerApplicationContext构造方法

SpringBoot源码系列文章 SpringBoot源码解析(一):SpringApplication构造方法 SpringBoot源码解析(二):引导上下文DefaultBootstrapContext SpringBoot源码解析(三):启动开始阶段 SpringBoot源码解析(四):解析应用参数args Sp…...

vue3+vite全局loading

vue3vite全局loading j-loading.vue组件 <template><transition enter-active-class"animate__animated animate__fadeIn"leave-active-class"animate__animated animate__fadeOut"><div class"root-box" v-if"show"…...

比亚迪发布智能化战略,天神之眼开创全民智驾

2月10日&#xff0c;比亚迪在深圳隆重召开智能化战略发布会&#xff0c;正式向全球发布了其最新的智驾技术——“天神之眼”。这一技术的发布&#xff0c;标志着比亚迪在智能驾驶领域迈出了坚实的一步&#xff0c;稳居行业第一梯队&#xff0c;真正实现了端到端的智能驾驶体验&…...

在 MySQL 中,通过存储过程结合条件判断来实现添加表字段时,如果字段已存在则不再重复添加

-- 创建存储过程 DELIMITER $$ CREATE PROCEDURE add_column(IN db_name VARCHAR(255),IN table_name VARCHAR(255),IN column_name VARCHAR(255),IN column_definition VARCHAR(255),IN column_comment VARCHAR(255) ) BEGINDECLARE column_exists INT;-- 检查字段是否存在SEL…...

UP-VLA:具身智体的统一理解与预测模型

25年1月来自清华大学和上海姚期智研究院的论文“UP-VLA: A Unified Understanding and Prediction Model for Embodied Agent”。 视觉-语言-动作 (VLA) 模型的最新进展&#xff0c;利用预训练的视觉语言模型 (VLM) 来提高泛化能力。VLM 通常经过视觉语言理解任务的预训练&…...

后端开发ThreadLocal简介

ThreadLocal是线程的局部变量&#xff0c;为每个线程单独提供一份存储空间&#xff0c;具有线程隔离的效果&#xff0c;只有线程内能获取到对应的值 客户端发起的每次请求都对应一个单独的线程 常用方法 public void set(T value) 设置当前线程局部变量值public T get() 返回…...

AI分支知识之机器学习,深度学习,强化学习的关系

机器学习&#xff0c;深度学习&#xff0c;强化学习的关系 这一篇文章我们来探讨下AI领域中机器学习&#xff08;ML&#xff09;、深度学习&#xff08;DL&#xff09;和强化学习&#xff08;RL&#xff09;的关系。 一、机器学习&#xff08;ML&#xff09;&#xff1a;从数…...

微信小程序案例2——天气微信小程序(学会绑定数据)

文章目录 一、项目步骤1 创建一个weather项目2 进入index.wxml、index.js、index.wxss文件,清空所有内容,进入App.json,修改导航栏标题为“中国天气网”。3进入index.wxml,进行当天天气情况的界面布局,包括温度、最低温、最高温、天气情况、城市、星期、风行情况,代码如下…...

CPLD实现SPI通信

在 CPLD 中编写 SPI 程序时,需根据具体需求(主/从设备、时钟极性、数据位宽等)设计逻辑。以下提供一个 SPI 主控制器的 Verilog 实现示例,支持 模式 0(CPOL=0, CPHA=0),适用于控制外设(如 ADC、DAC、存储器等)。 SPI 主控制器模块设计(Verilog) 模块功能 支持 8/16…...

FFmpeg + OpenGL ES 美颜相机教程大纲

做OpenGL和FFmpeg也有很长一段时间了&#xff0c;最近打算结合FFmpegOpenGL ES做一期视频教程&#xff0c;下面是完整视频教程大纲。最终的项目实战效果是实现一款美颜相机。教程分为理论讲解和实战开发两部分&#xff0c;适合有一定编程基础的开发者。课程计划是免费发布在B站…...

dynamic_cast和static_cast和const_cast

dynamic_cast 在 C 中的作用 dynamic_cast 是 C 运行时类型转换&#xff08;RTTI, Run-Time Type Identification&#xff09;的一部分&#xff0c;主要用于&#xff1a; 安全的多态类型转换检查类型的有效性向下转换&#xff08;Downcasting&#xff09;跨类层次的指针或引用…...