Ollama
什么是 Ollama?
Ollama 是一个先进的 AI 工具,允许用户轻松地在本地设置和运行大型语言模型(支持 CPU 和 GPU 模式)。使用 Ollama,用户可以利用强大的语言模型,如 Llama 2,甚至可以自定义和创建自己的模型。Ollama 将模型权重、配置和数据打包成一个单一的包,由 Modelfile 定义。它优化了设置和配置细节,包括 GPU 使用。
有关 Ollama 的更多详情,请查看:
演讲
观看在 Docker Con 23 的演讲:
观看 Code to the Moon 的介绍:
入门
要开始使用,请将以下依赖项添加到项目的 pom.xml 中:
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-ollama</artifactId>
<version>1.0.0-beta3</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>ollama</artifactId>
<version>1.19.1</version>
</dependency>
当 Ollama 在 testcontainers 中运行时,尝试一个简单的聊天示例代码:
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.model.Image;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.ollama.OllamaChatModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.containers.Container;
import org.testcontainers.ollama.OllamaContainer;
import org.testcontainers.utility.DockerImageName;
import java.io.IOException;
import java.util.List;
public class OllamaChatExample {
private static final Logger log = LoggerFactory.getLogger(OllamaChatExample.class);
static final String OLLAMA_IMAGE = "ollama/ollama:latest";
static final String TINY_DOLPHIN_MODEL = "tinydolphin";
static final String DOCKER_IMAGE_NAME = "tc-ollama/ollama:latest-tinydolphin";
public static void main(String[] args) {
// 创建并启动 Ollama 容器
DockerImageName dockerImageName = DockerImageName.parse(OLLAMA_IMAGE);
DockerClient dockerClient = DockerClientFactory.instance().client();
List<Image> images = dockerClient.listImagesCmd().withReferenceFilter(DOCKER_IMAGE_NAME).exec();
OllamaContainer ollama;
if (images.isEmpty()) {
ollama = new OllamaContainer(dockerImageName);
} else {
ollama = new OllamaContainer(DockerImageName.parse(DOCKER_IMAGE_NAME).asCompatibleSubstituteFor(OLLAMA_IMAGE));
}
ollama.start();
// 拉取模型并基于所选模型创建镜像
try {
log.info("开始拉取 '{}' 模型... 可能需要几分钟...", TINY_DOLPHIN_MODEL);
Container.ExecResult r = ollama.execInContainer("ollama", "pull", TINY_DOLPHIN_MODEL);
log.info("模型拉取完成!{}", r);
} catch (IOException | InterruptedException e) {
throw new RuntimeException("拉取模型时出错", e);
}
ollama.commitToImage(DOCKER_IMAGE_NAME);
// 构建 ChatLanguageModel
ChatLanguageModel model = OllamaChatModel.builder()
.baseUrl(ollama.getEndpoint())
.temperature(0.0)
.logRequests(true)
.logResponses(true)
.modelName(TINY_DOLPHIN_MODEL)
.build();
// 示例用法
String answer = model.chat("提供3个简短的要点解释为什么Java很棒");
System.out.println(answer);
// 停止 Ollama 容器
ollama.stop();
}
}
如果您的 Ollama 在本地运行,您也可以尝试以下聊天示例代码:
class OllamaChatLocalModelTest {
static String MODEL_NAME = "llama3.2"; // 尝试其他本地 ollama 模型名称
static String BASE_URL = "http://localhost:11434"; // 本地 ollama 基础 URL
public static void main(String[] args) {
ChatLanguageModel model = OllamaChatModel.builder()
.baseUrl(BASE_URL)
.modelName(MODEL_NAME)
.build();
String answer = model.chat("列出中国前10大城市");
System.out.println(answer);
model = OllamaChatModel.builder()
.baseUrl(BASE_URL)
.modelName(MODEL_NAME)
.responseFormat(JSON)
.build();
String json = model.chat("列出美国前10大城市");
System.out.println(json);
}
}
当 Ollama 在 testcontainers 中运行时,尝试一个简单的流式聊天示例代码:
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.model.Image;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.ollama.OllamaStreamingChatModel;
import dev.langchain4j.model.output.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.containers.Container;
import org.testcontainers.ollama.OllamaContainer;
import org.testcontainers.utility.DockerImageName;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public class OllamaStreamingChatExample {
private static final Logger log = LoggerFactory.getLogger(OllamaStreamingChatExample.class);
static final String OLLAMA_IMAGE = "ollama/ollama:latest";
static final String TINY_DOLPHIN_MODEL = "tinydolphin";
static final String DOCKER_IMAGE_NAME = "tc-ollama/ollama:latest-tinydolphin";
public static void main(String[] args) {
DockerImageName dockerImageName = DockerImageName.parse(OLLAMA_IMAGE);
DockerClient dockerClient = DockerClientFactory.instance().client();
List<Image> images = dockerClient.listImagesCmd().withReferenceFilter(DOCKER_IMAGE_NAME).exec();
OllamaContainer ollama;
if (images.isEmpty()) {
ollama = new OllamaContainer(dockerImageName);
} else {
ollama = new OllamaContainer(DockerImageName.parse(DOCKER_IMAGE_NAME).asCompatibleSubstituteFor(OLLAMA_IMAGE));
}
ollama.start();
try {
log.info("开始拉取 '{}' 模型... 可能需要几分钟...", TINY_DOLPHIN_MODEL);
Container.ExecResult r = ollama.execInContainer("ollama", "pull", TINY_DOLPHIN_MODEL);
log.info("模型拉取完成!{}", r);
} catch (IOException | InterruptedException e) {
throw new RuntimeException("拉取模型时出错", e);
}
ollama.commitToImage(DOCKER_IMAGE_NAME);
StreamingChatLanguageModel model = OllamaStreamingChatModel.builder()
.baseUrl(ollama.getEndpoint())
.temperature(0.0)
.logRequests(true)
.logResponses(true)
.modelName(TINY_DOLPHIN_MODEL)
.build();
String userMessage = "写一首关于Java和AI的100字诗";
CompletableFuture<ChatResponse> futureResponse = new CompletableFuture<>();
model.chat(userMessage, new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String partialResponse) {
System.out.print(partialResponse);
}
@Override
public void onCompleteResponse(ChatResponse completeResponse) {
futureResponse.complete(completeResponse);
}
@Override
public void onError(Throwable error) {
futureResponse.completeExceptionally(error);
}
});
futureResponse.join();
ollama.stop();
}
}
如果您的 Ollama 在本地运行,您也可以尝试以下流式聊天示例代码:
class OllamaStreamingChatLocalModelTest {
static String MODEL_NAME = "llama3.2"; // 尝试其他本地 ollama 模型名称
static String BASE_URL = "http://localhost:11434"; // 本地 ollama 基础 URL
public static void main(String[] args) {
StreamingChatLanguageModel model = OllamaStreamingChatModel.builder()
.baseUrl(BASE_URL)
.modelName(MODEL_NAME)
.temperature(0.0)
.build();
String userMessage = "写一首关于Java和AI的100字诗";
CompletableFuture<ChatResponse> futureResponse = new CompletableFuture<>();
model.chat(userMessage, new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String partialResponse) {
System.out.print(partialResponse);
}
@Override
public void onCompleteResponse(ChatResponse completeResponse) {
futureResponse.complete(completeResponse);
}
@Override
public void onError(Throwable error) {
futureResponse.completeExceptionally(error);
}
});
futureResponse.join();
}
}
参数
OllamaChatModel 和 OllamaStreamingChatModel 类可以使用构建器模式实例化,具有以下参数:
| 参数 | 描述 | 类型 | 示例 |
|---|---|---|---|
baseUrl | Ollama 服务器的基础 URL。 | String | http://localhost:11434 |
modelName | 从 Ollama 服务器使用的模型名称。 | String | |
temperature | 控制生成响应的随机性。较高的值(例如 1.0)会产生更多样化的输出,而较低的值(例如 0.2)会产生更确定性的响应。 | Double | |
topK | 指定在生成过程中每一步考虑的最高概率标记的数量。 | Integer | |
topP | 通过设置顶部标记累积概率的阈值来控制生成响应的多样性。 | Double | |
repeatPenalty | 对模型在生成输出中重复类似标记进行惩罚。 | Double | |
seed | 设置随机种子以使生成的响应可重现。 | Integer | |
numPredict | 为每个输入提示生成的预测数量。 | Integer | |
stop | 如果生成,将标记响应结束的字符串列表。 | List<String> | |
format | 生成输出的所需格式。(已弃用,请参见 responseFormat) | String | |
responseFormat | 生成输出的所需格式。TEXT 或 JSON,可选带有 JSON Schema 定义 | ResponseFormat | |
supportedCapabilities | 由 AiServices API 使用的模型能力集(仅支持 OllamaChatModel) | Capability | RESPONSE_FORMAT_JSON_SCHEMA |
timeout | API 调用完成的最大允许时间。 | Duration | PT60S |
maxRetries | API 调用失败时的最大重试次数。 | Integer |
使用示例
OllamaChatModel ollamaChatModel = OllamaChatModel.builder()
.baseUrl("http://localhost:11434")
.modelName("llama3.1")
.temperature(0.8)
.timeout(Duration.ofSeconds(60))
.build();
使用 Spring Boot 的示例
langchain4j.ollama.chat-model.base-url=http://localhost:11434
langchain4j.ollama.chat-model.model-name=llama3.1
langchain4j.ollama.chat-model.temperature=0.8
langchain4j.ollama.chat-model.timeout=PT60S
JSON 模式
使用构建器的 JSON 模式
OllamaChatModel ollamaChatModel = OllamaChatModel.builder()
.baseUrl("http://localhost:11434")
.modelName("llama3.1")
.responseFormat(ResponseFormat.JSON)
.temperature(0.8)
.timeout(Duration.ofSeconds(60))
.build();
使用构建器的 JSON 模式 已弃用
OllamaChatModel ollamaChatModel = OllamaChatModel.builder()
.baseUrl("http://localhost:11434")
.modelName("llama3.1")
.format("json")
.temperature(0.8)
.timeout(Duration.ofSeconds(60))
.build();
结构化输出
使用构建器的 JSON schema 定义
OllamaChatModel ollamaChatModel = OllamaChatModel.builder()
.baseUrl("http://localhost:11434")
.modelName("llama3.1")
.responseFormat(ResponseFormat.builder()
.type(ResponseFormatType.JSON)
.jsonSchema(JsonSchema.builder().rootElement(JsonObjectSchema.builder()
.addProperty("name", JsonStringSchema.builder().build())
.addProperty("capital", JsonStringSchema.builder().build())
.addProperty(
"languages",
JsonArraySchema.builder()
.items(JsonStringSchema.builder().build())
.build())
.required("name", "capital", "languages")
.build())
.build())
.build())
.temperature(0.8)
.timeout(Duration.ofSeconds(60))
.build();