成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何在Ollama和Spring AI上使用本地AI/LLM查詢圖像數(shù)據(jù)庫

譯文
人工智能
本文介紹如何利用Ollama LLava模型和Spring AI,實現(xiàn)基于自然語言的圖像數(shù)據(jù)庫查詢,并支持高效向量搜索和圖像描述展示。

譯者 | 李睿

審校 | 重樓

AIDocumentLibraryChat項目的功能已經(jīng)擴展到可以查詢圖像的圖像數(shù)據(jù)庫。它使用了可以分析圖像的Ollama的LLava模型。圖像搜索功能利用PostgreSQL的PGVector擴展來處理嵌入(Embeddings)

架構

AIDocumentLibraryChat項目的架構見下圖:

Angular前端向用戶展示上傳和提問功能。Spring AI后端可以調(diào)整模型的圖像大小,使用數(shù)據(jù)庫存儲數(shù)據(jù)/向量,并使用Ollama的LLava模型創(chuàng)建圖像描述。

圖像上傳/分析/存儲流程見下圖:

圖像通過前端上傳。后端將其調(diào)整為LLava模型可以處理的格式。然后,LLava模型根據(jù)提供的提示生成圖像的描述。調(diào)整之后的圖像和元數(shù)據(jù)存儲在PostgreSQL的關系表中。然后使用圖像描述來創(chuàng)建嵌入。嵌入與元數(shù)據(jù)一起存儲在PGVector數(shù)據(jù)庫中的描述中,以在PostgreSQL表中找到相應的行。然后在前端顯示圖像描述和調(diào)整后的圖像。

圖像查詢的流程見下圖:

用戶可以在前端輸入問題。后端將問題轉換為嵌入,并在PGVector數(shù)據(jù)庫中搜索最近的條目。該條目包含圖像表中包含圖像和元數(shù)據(jù)的行ID然后,將圖像表數(shù)據(jù)與描述一起查詢并顯示給用戶。

后端

為了運行PGVector數(shù)據(jù)庫和Ollama框架,runPostgresql.sh和runOllama.sh文件中包含Docker命令。

后端需要application-ollama.properties文件配置以下條目

Properties files 
 # image processing
 spring.ai.ollama.chat.model=llava:34b-v1.6-q6_K
 spring.ai.ollama.chat.options.num-thread=8
 spring.ai.ollama.chat.options.keep_alive=1s

該應用程序需要使用Ollama支持(屬性:‘useOllama’)構建,并使用‘Ollama’配置文件啟動,需要激活這些屬性以啟用LLava模型并設置有用的keep_alive。只有當Ollama沒有自動選擇正確的線程數(shù)量時,才需要設置num_thread。

控制器(Controller

ImageController包含以下端點:

Java 
 @RestController
 @RequestMapping("rest/image")
 public class ImageController {
 ...
 @PostMapping("/query")
 public List<ImageDto> postImageQuery(@RequestParam("query") String 
 query,@RequestParam("type") String type) { 
 var result = this.imageService.queryImage(query); 
 return result;
 }
 
 @PostMapping("/import")
 public ImageDto postImportImage(@RequestParam("query") String query, 
 @RequestParam("type") String type, 
 @RequestParam("file") MultipartFile imageQuery) { 
 var result = 
 this.imageService.importImage(this.imageMapper.map(imageQuery, query), 
 this.imageMapper.map(imageQuery)); 
 return result;
 } 
 }

查詢端點包含‘postImageQuery(…)’方法,該方法接收包含查詢和圖像類型的表單,并調(diào)用ImageService來處理請求。

導入端點包含‘postImportImage(…)’方法,該方法接收帶有查詢(提示)、圖像類型和文件的表單。ImageMapper將表單轉換為ImageQueryDto和Image實體,并調(diào)用ImageService來處理請求。

服務

調(diào)用ImageService如下:

Java 
 @Service
 @Transactional
 public class ImageService {
 ...
 public ImageDto importImage(ImageQueryDto imageDto, Image image) {
 var resultData = this.createAIResult(imageDto);
 image.setImageContent(resultData.imageQueryDto().getImageContent());
 var myImage = this.imageRepository.save(image);
 var aiDocument = new Document(resultData.answer());
 aiDocument.getMetadata().put(MetaData.ID, myImage.getId().toString());
 aiDocument.getMetadata().put(MetaData.DATATYPE, 
 MetaData.DataType.IMAGE.toString());
 this.documentVsRepository.add(List.of(aiDocument));
 return new ImageDto(resultData.answer(), 
 Base64.getEncoder().encodeToString(resultData.imageQueryDto()
 .getImageContent()), resultData.imageQueryDto().getImageType());
 }

 public List<ImageDto> queryImage(String imageQuery) {
 var aiDocuments = this.documentVsRepository.retrieve(imageQuery, 
 MetaData.DataType.IMAGE, this.resultSize.intValue())
 .stream().filter(myDoc -> myDoc.getMetadata()
 .get(MetaData.DATATYPE).equals(DataType.IMAGE.toString()))
 .sorted((myDocA, myDocB) -> 
 ((Float) myDocA.getMetadata().get(MetaData.DISTANCE))
 .compareTo(((Float) myDocB.getMetadata().get(MetaData.DISTANCE))))
 .toList();
 var imageMap = this.imageRepository.findAllById(
 aiDocuments.stream().map(myDoc -> 
 (String) myDoc.getMetadata().get(MetaData.ID)).map(myUuid -> 
 UUID.fromString(myUuid)).toList())
 .stream().collect(Collectors.toMap(myDoc -> myDoc.getId(), 
 myDoc -> myDoc));
 return imageMap.entrySet().stream().map(myEntry -> 
 createImageContainer(aiDocuments, myEntry))
 .sorted((containerA, containerB) -> 
 containerA.distance().compareTo(containerB.distance()))
 .map(myContainer -> new ImageDto(myContainer.document().getContent(), 
 Base64.getEncoder().encodeToString(
 myContainer.image().getImageContent()),
 myContainer.image().getImageType())).limit(this.resultSize)
 .toList();
 }

 private ImageContainer createImageContainer(List<Document> aiDocuments, 
 Entry<UUID, Image> myEntry) {
 return new ImageContainer(
 createIdFilteredStream(aiDocuments, myEntry)
 .findFirst().orElseThrow(),
 myEntry.getValue(),
 createIdFilteredStream(aiDocuments, myEntry).map(myDoc -> 
 (Float) myDoc.getMetadata().get(MetaData.DISTANCE))
 .findFirst().orElseThrow());
 }

 private Stream<Document> createIdFilteredStream(List<Document> aiDocuments, 
 Entry<UUID, Image> myEntry) {
 return aiDocuments.stream().filter(myDoc -> myEntry.getKey().toString()
 .equals((String) myDoc.getMetadata().get(MetaData.ID)));
 }

 private ResultData createAIResult(ImageQueryDto imageDto) {
 if (ImageType.JPEG.equals(imageDto.getImageType()) || 
 ImageType.PNG.equals(imageDto.getImageType())) {
 imageDto = this.resizeImage(imageDto);
 } 
 var prompt = new Prompt(new UserMessage(imageDto.getQuery(), 
 List.of(new Media(MimeType.valueOf(imageDto.getImageType()
 .getMediaType()), imageDto.getImageContent()))));
 var response = this.chatClient.call(prompt);
 var resultData = new 
 ResultData(response.getResult().getOutput().getContent(), imageDto);
 return resultData;
 }

 private ImageQueryDto resizeImage(ImageQueryDto imageDto) {
 ...
 }
 }

importImage(…)方法中,將調(diào)用createAIResult(…)方法。它檢查圖像類型,并調(diào)用resizeImage(…)方法將圖像縮放到LLava模型支持的大小。然后使用提示文本和包含圖像、媒體類型和圖像字節(jié)數(shù)組的媒體創(chuàng)建Spring AI Prompt。然后,chatClient調(diào)用提示,并在‘ResultData記錄中返回響應,其中包含描述和調(diào)整大小的圖像。然后將調(diào)整大小的圖像添加到圖像實體中,并保留該實體。然后,在元數(shù)據(jù)中創(chuàng)建了包含嵌入、描述和圖像實體ID的AI文檔。最后使用描述、調(diào)整大小的圖像和圖像類型創(chuàng)建ImageDto并返回。

queryImage(…)’方法中,檢索并過濾元數(shù)據(jù)中圖像類型的AI文檔的最低距離的Spring AI文檔。按照最小的距離對文檔進行排序。然后加載帶有Spring AI文檔元數(shù)據(jù)ID的圖像實體。這樣就可以創(chuàng)建具有匹配文檔和圖像實體的ImageDtos。圖像以Base64編碼字符串的形式提供。這使得MediaType可以輕松地在IMG標簽中顯示圖像。

要顯示Base64 Png圖像,可以使用:‘<img src=”data:image/png;base64,iVBORw0KG…” />’

結果

用戶界面(UI)的結果見下圖:

該應用程序使用嵌入在向量數(shù)據(jù)庫中找到大型飛機。選擇第二張圖像是因為天空相似,而圖像搜索只花了不到一秒的時間。

結論

Spring AI和Ollama的支持為用戶提供了使用免費LLava模型的機會,這使得該圖像數(shù)據(jù)庫的實現(xiàn)變得容易。LLava模型可以生成圖像的良好描述,這些描述可以轉換為嵌入以進行快速搜索。Spring AI缺少對生成API端點的支持,因為參數(shù)‘spring.ai.ollama.chat.options.keep_alive=1s’需要Keep_alive =1s '來避免上場景窗口中有舊數(shù)據(jù)。LLava模型需要GPU加速才能有效使用。LLava僅用于導入,這意味著描述的創(chuàng)建可以異步完成。在中等性能的筆記本電腦上,LLava模型在一個CPU上運行,每張圖像的處理時間為510分鐘。與以前的實現(xiàn)相比,這樣的圖像搜索解決方案是一個巨大的進步。隨著采用更多GPU或CPU對人工智能的支持,這樣的圖像搜索解決方案將變得更加流行。

原文標題Questioning an Image Database With Local AI/LLM on Ollama and Spring AI作者:Sven Loesekann

責任編輯:華軒 來源: 51CTO
相關推薦

2025-03-31 09:30:52

2023-07-28 08:00:00

人工智能向量數(shù)據(jù)庫

2020-09-11 10:59:05

數(shù)據(jù)庫

2025-03-28 07:33:09

數(shù)據(jù)庫AI助手設計

2020-09-10 18:14:51

人工智能 IBM

2024-09-06 11:34:15

RustAI語言

2011-03-24 17:28:58

網(wǎng)絡數(shù)據(jù)庫

2011-07-26 14:34:28

openSUSEpostgresql

2024-06-04 12:59:41

2024-12-12 08:26:50

AI模型LLM大語言模型

2023-05-24 08:52:12

2025-03-27 09:34:42

2017-06-13 10:15:50

人工智能深度學習神經(jīng)網(wǎng)絡

2024-05-22 12:07:12

向量數(shù)據(jù)庫AI

2019-12-11 14:27:39

數(shù)據(jù)庫集群Kubernetes

2024-10-30 11:06:59

SpringAI模型

2009-01-19 09:14:31

.NETMySQLMySql驅動包

2023-09-15 08:00:20

2022-08-03 10:45:04

人工智能網(wǎng)絡安全
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品一级 | julia中文字幕久久一区二区 | 欧美日在线 | 在线观看黄视频 | 一级a性色生活片久久毛片 一级特黄a大片 | 日韩成人av在线播放 | xnxx 日本免费 | 龙珠z在线观看 | 在线观看国产 | a在线视频观看 | 一级黄色绿像片 | 亚洲成av人片在线观看无码 | 精品一区国产 | 亚洲天堂一区 | 99re在线视频| 午夜久久久久久久久久一区二区 | 国产日韩欧美在线一区 | 在线免费观看黄色 | 99re6热在线精品视频播放 | 黄色片视频免费 | 日韩三级在线 | 精品乱码一区二区三四区 | 国产精品永久免费视频 | 国产日韩欧美一区二区 | 色综合99 | 91资源在线| 69精品久久久久久 | av一区二区三区四区 | 中文在线a在线 | 国产在线一区二区三区 | 亚洲欧美另类在线 | 国产欧美视频一区二区 | av色在线 | 精品区一区二区 | 日韩在线三级 | 精品视频一区二区三区 | 最新中文字幕在线 | 欧美激情一区二区三级高清视频 | 亚洲精品乱码久久久久久9色 | 亚洲三区在线观看 | 国产精品美女久久久免费 |