零基础入门Java+大模型(持续更新)
0.初始一些常见的概念
AI:人工智能
大模型划分:(本章了解一下这个就行)NLP模型-->自然语言模型(AI现在爆火的原因,就是自然语言模型这一块取得了很大的成就)。
LLM:大语言模型(包含在自然语言模型里面的)。
目前比较火的模型提供商有:谷歌,微软,阿里。
生态:
应用:使用ollama工具大模型本地部署(注意点:qwen deepseek 基于docker,不要在虚拟机中部署),openwebUI客户端/anything(基于restAPI实现的)。
大模型开发:python-> numpy pandas pytorch transflower。
1.ollama使用的一些命令行
ollama的官网:Ollama
进去官网后,傻瓜式安装就行了。
注意:先在本地电脑安装docker环境,再安装ollama。
docker的官网:Docker: Accelerated Container Application Development
同样也是傻瓜式安装。
ollama和docker的命令行可以说是一模一样,直接ollama help 来查看ollama的使用!
ollama的默认端口号是:11434
2.openwebUI客户端(了解即可)
这些客户端的本质都是调用那些模型提供商的api接口,用restAPI形式去调用。
3.Java+AI的生态图
4.Spring AI
本质就是一个java的rest客户端
SpringBoot的版本不要低于3.2.x
ChatClient客户端的使用:
1.依赖(注意ChatCLient不支持多模型同时存在 )
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.1</version><relativePath/> <!-- lookup parent from repository --></parent><!-- Generated by https://start.springboot.io --><!-- 优质的 spring/boot/data/security/cloud 框架中文文档尽在 => https://springdoc.cn --><groupId>com.atguigu</groupId><artifactId>ai-demo</artifactId><version>0.0.1-SNAPSHOT</version><name>ai-demo</name><description>ai-demo</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>17</java.version><spring-ai.version>1.0.0-M4</spring-ai.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- ChatClient不支持多模型,需要把其中一个模型注释掉 --><!--<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-ollama-spring-boot-starter</artifactId></dependency>--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository></repositories></project>
2.添加配置
spring.application.name=ai-demoserver.port=10086# 配置openai的地址,使用了中转地址
spring.ai.openai.base-url=https://api.xty.app
spring.ai.openai.api-key=sk-xx
# 配置聊天模型
spring.ai.openai.chat.options.model=gpt-3.5-turbo
3.编写配置类初始化ChatClient对象
@Configuration
public class ChatClientConfig {@Beanpublic ChatClient chatClient(ChatClient.Builder chatClientBuilder){return chatClientBuilder.defaultSystem("XXX") // 全局的外挂.build();}
}
4.Controller方法:
@RestController
class MyController {@Autowiredprivate ChatClient chatClient;@GetMapping("/ai")String generation(String userInput) {return this.chatClient.prompt().user(userInput).call()// 同步方式,一次性输出答案.content();}/*** flux是输入响应式的输出,流式方式输出到前端页面* produces:设置响应信息的编码** @param userInput* @return*/@GetMapping(value = "/stream", produces = "text/plain;charset=UTF-8")Flux<String> stream(String userInput) {return this.chatClient.prompt().user(userInput)
// .system("XXX").stream() // 流式输出.content();}/*** 演示chatResponse中的内容** @param userInput* @return*/@GetMapping("resp")String resp(String userInput) {ChatResponse chatResponse = chatClient.prompt().user("Tell me a joke").call().chatResponse();System.out.println(chatResponse.getMetadata().toString());System.out.println(chatResponse.getResults());return chatResponse.getResult().getOutput().getContent(); // 获取最终输出}
}
5.联系上下文:(要知道Message有4种角色:user ,assistant , system , tool;其中发挥上下文的关键是assistant)
/*** 联系上下文回答用户的提问:system、user\Assistant tool* @param userInput* @return*/@GetMapping(value = "context", produces = "text/plain;charset=UTF-8")Flux<String> context(String userInput) {return chatClient.prompt(new Prompt(new UserMessage("刘德华是谁"),new AssistantMessage("刘德华(Andy Lau),是香港著名的演员、歌手、制作人和电影监制。他是华语娱乐圈的超级明星之一,被誉为“四大天王”之一,与张学友、郭富城、黎明一起,代表了90年代至2000年代的香港乐坛和影坛。\n" +"\n" +"刘德华1961年出生于香港,从1980年代出道后,凭借其出色的演技、唱功和敬业精神,迅速积累了大量的粉丝。他不仅在电影中塑造了许多经典角色,还发行了大量畅销音乐专辑。\n" +"\n" +"他在电影方面的代表作品包括《无间道》、《暗战》、《赌神》等,而在音乐方面,他也有许多脍炙人口的歌曲,比如《冰雨》、《忘情水》、《十年》等。\n" +"\n" +"刘德华的个人形象一直保持积极正面,他以“全能艺人”著称,涵盖了演员、歌手、制作人等多个领域,且长期参与慈善事业。他的影响力跨越了多个行业和地区,是华语娱乐圈最具影响力和号召力的明星之一。"),new UserMessage(userInput))).stream().content();}
4.1 OpenAiChatModel
聊天模型
@RestController
@RequestMapping("openai")
public class OpenAiController {@Autowiredprivate OpenAiChatModel openAiChatModel;@GetMapping("generate")String generate(String userInput){// call方法中可以放Prompt对象 Message对象 提问字符串return this.openAiChatModel.call(userInput);}// 自行扩展联系上下文怎么聊天@GetMapping(value = "stream", produces = "text/plain;charset=UTF-8")Flux<String> stream(String userInput){// call方法中可以放Prompt对象 Message对象 提问字符串return this.openAiChatModel.stream(userInput);}@GetMapping(value = "stream2", produces = "text/plain;charset=UTF-8")Flux<String> stream2(String userInput){// call方法中可以放Prompt对象 Message对象 提问字符串Flux<ChatResponse> chatResponseFlux = this.openAiChatModel.stream(new Prompt(userInput,OpenAiChatOptions.builder().withModel("llama3-70b").build()));return chatResponseFlux.map(response -> response.getResult() == null || response.getResult().getOutput() == null || response.getResult().getOutput().getContent() == null ? "" : response.getResult().getOutput().getContent());}
}
4.2 openAiImageModel
图片模型
# application.properties
# 配置图片模型
spring.ai.openai.image.options.model=dall-e-3@GetMapping("image")
String image(String userInput){ImageResponse response = openAiImageModel.call(new ImagePrompt(userInput,OpenAiImageOptions.builder().withQuality("hd")// .withN(4) 生成图片的数量.withHeight(1024).withWidth(1024).build()));return "<image src='" + response.getResult().getOutput().getUrl() + "'>";
}
4.3 OpenAiAudioSpeechOptions
音频模型
# 配置音频模型
spring.ai.openai.audio.speech.options.model=tts-1@GetMapping("audio")
String audio(String userInput) throws IOException {OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder().withVoice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY).withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3).withSpeed(1.0f).build();SpeechPrompt speechPrompt = new SpeechPrompt(userInput, speechOptions);SpeechResponse response = openAiAudioSpeechModel.call(speechPrompt);byte[] output = response.getResult().getOutput();// input --> 内存 --> outputFileOutputStream stream = new FileOutputStream("output.mp3");stream.write(output);stream.close();return "音频生成成功。。。。";
}
4.4 多模态模型
# 配置聊天模型
spring.ai.openai.chat.options.model=gpt-4-turbo@GetMapping("moderation")String moderation(String userInput){ClassPathResource resource = new ClassPathResource("multimodal.test.png");var userMessage = new UserMessage(userInput, // contentList.of(new Media(MimeTypeUtils.IMAGE_PNG, resource))); // mediaChatResponse response = this.openAiChatModel.call(new Prompt(List.of(userMessage)));return response.getResult().getOutput().getContent();// ModerationPrompt moderationPrompt = new ModerationPrompt();
// ModerationResponse response = openAiModerationModel.call(moderationPrompt);
//
// Moderation moderation = response.getResult().getOutput();}
5.向量数据库(Vector DB)
RAG:检索增强生成,方式:
-
函数调用:气象信息
-
微调:门槛太高
-
提示填充:例如system设置系统信息(向量数据库,本地知识库)、user用户填充、assist问答填充
安装
(安装在docker环境中,这里使用Qdrant向量数据库)
docker run -d --name qdrant -p 6333:6333 -p 6334:6334 -v D:\\Resource\\docker\\storage\\qdrant:/qdrant/storage:z qdrant/qdrant
RestAPI:6333
GRPC:6334 性能更高,延迟更低,兼容性没有restAPI高(因为Java兼容这个GPRC所以后期也会用GRPC)。
概念学习(类比mysql学习)
首先要清楚Qdrant是没有mysql中的库的概念的,只有类似于mysql中的表table,行row,字段概念。
collection:集合 相当于mysql中table,维度必须一致,创建集合时需要指定维度和距离度量:
维度(与后面点坐标有联系)可以自定义,距离度量有以下4种可以选:
- 余弦相似度(Cosine):0表示两个事务完全不相似,1表示两个事物完全相似。文本
- 点积(Dot):点积相似度通过将两组数字中的值相乘,然后将这些乘积加起来来计算得到。越高的总和意味着两组数字越相似。图片
- 欧式距离(Euclidean):两点坐标之间差值的平方和的平方根。
- 曼哈顿距离(Manhattan ):它表示两个点在标准坐标系上的绝对轴距总和。曼哈顿距离是标量空间中两点间各维度差的绝对值之和。
point:点,相当于mysql中的记录row
点的组成如下:
id:主键
vector:点坐标,是一个数字的集合,集合中元素数量取决于维度
payload:具体内容,一般使用json表示-->有效载荷:实际的内容
向量(其实就是上面的点坐标):Vector
密集向量:传统向量,一个个的浮点型数据集合
稀疏向量:indices: [1, 3, 5, 7] values: [0.1, 0.2, 0.3, 0.4]
多向量:[[],[],[]]
命名向量:
1.集合的操作:
查询集合列表
GET /collections新建集合
PUT collections/集合的名字
{"vectors": {"size"维度: 5,"distance"距离度量: "Cosine"}
}// 获取集合的详细信息
GET collections/集合的名字// 更新集合参数
PATCH collections/集合的名字
{"hnsw_config": {"on_disk": true}
}// 删除集合
DELETE collections/集合的名字// 判断一个集合是否存在
GET collections/集合的名字/exists
2.点的操作:
新增点
PUT /collections/test/points
{"points": [{"id": 1,"payload": {"name": "zhangsan","age": 23,"gender": "男"},"vector": [0.5, 0.6, 0.2, 0.7, 0.9]},{"id": 2,"payload": {"name": "李四","age": 24,"gender": "男"},"vector": [0.6, 0.3, 0.5, 0.2, 0.7]}]
}// 批量新增点
PUT collections/test/points
{"batch": {"ids": [3, 4, 5],"payloads": [{"name": "王五","age": 25,"gender": "男"},{"name": "赵六","age": 26,"gender": "女"},{"name": "钱七","age": 27,"gender": "女"}],"vectors": [[0.4, 0.6, 0.7, 0.4, 0.8],[0.8, 0.3, 0.6, 0.6, 0.3],[0.4, 0.6, 0.2, 0.1, 0.2]]}
}// 查看一个点的信息
GET collections/test/points/3// 根据ids查看多个点
POST collections/test/points
{"ids": [1,3,5],"with_payload": true,"with_vector": true
}// 分页查询点
POST collections/test/points/scroll
{"limit": 5,"with_vector": true
}// 删除点
POST collections/test/points/delete
{"points": [1, 3]
}// 修改点的向量
PUT collections/test/points/vectors
{"points": [{"id": 1,"vector": [0.6, 0.7, 0.8, 0.9, 0]}]
}// 修改点的载荷信息
POST collections/test/points/payload
{"points": [1, 3],"payload": {"age": 30}
}
6.Java客户端
官方客户端:
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-vector-store-qdrant</artifactId>
</dependency>
@Autowired VectorStore vectorStore;// ...List<Document> documents = List.of(new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("meta1", "meta1")),new Document("The World is Big and Salvation Lurks Around the Corner"),new Document("You walk forward facing the past and you turn back toward the future.", Map.of("meta2", "meta2")));// Add the documents to Qdrant
vectorStore.add(documents);// Retrieve documents similar to a query
List<Document> results = vectorStore.similaritySearch(SearchRequest.builder().query("Spring").topK(5).build());
SpringAI官网也提供了过滤条件的玩法: