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

CLIP ViT-H-14实战教程:与LangChain集成构建多模态RAG知识库

CLIP ViT-H-14实战教程:与LangChain集成构建多模态RAG知识库

1. 引言:当图片也能“说话”时

想象一下,你有一个庞大的图片库,里面有产品图、设计稿、历史照片,甚至是你随手拍的风景。现在,你想找一张“夕阳下的海边小屋”,或者“穿着红色裙子的女孩在跳舞”。传统的搜索方式,要么靠你手动打标签,要么靠文件名,效率低不说,还常常找不到。

这就是我们今天要解决的问题。CLIP ViT-H-14,这个由OpenAI开源的强大模型,能让计算机真正“看懂”图片,并用文字去理解它。而LangChain,则是当前最火的AI应用开发框架,能把各种AI能力像乐高积木一样组合起来。

把它们俩结合起来,我们能做什么?我们可以构建一个多模态检索增强生成(RAG)知识库。简单说,就是让AI不仅能根据文字搜文字,还能根据文字搜图片,甚至根据图片搜相关的文字资料。这对于内容管理、电商、设计、教育等领域,简直是革命性的工具。

这篇教程,我将手把手带你,从零开始部署CLIP服务,到最终与LangChain集成,打造一个属于你自己的、能“图文互搜”的智能知识库。整个过程清晰明了,哪怕你之前没接触过这些技术,也能跟着一步步做出来。

2. 环境准备与CLIP服务部署

万事开头难,但部署CLIP服务这一步,我们已经有人帮我们铺好了路。我们将使用一个预打包好的服务镜像,它省去了我们安装依赖、下载模型等繁琐步骤。

2.1 理解我们的工具:CLIP ViT-H-14服务

在动手之前,我们先快速了解一下我们将要启动的这个服务是什么。

  • 核心模型:CLIP ViT-H-14 (laion2B-s32B-b79K)。这是一个在超大规模图文对(LAION-2B)上训练过的视觉-语言模型。“ViT-H-14”代表它使用Vision Transformer架构,并且是“Huge”版本,有14x14的patch大小,能力非常强。
  • 它能做什么:这个服务启动后,会做两件核心事:
    1. 提取图片特征:你给它一张图片,它能输出一个1280维的数学向量(可以理解为这张图片的“数字指纹”)。
    2. 计算图文相似度:你给它一张图和一段文字,它能告诉你它们有多匹配。
  • 提供服务的方式
    • Web界面:一个简单的网页,你可以上传图片,查看提取的特征,或者测试图文匹配。
    • RESTful API:这才是我们需要的。我们可以通过发送HTTP请求,让其他程序(比如我们的LangChain应用)来调用图片特征提取功能。

2.2 一键启动服务

假设你已经拥有了这个服务的运行环境(例如一个预装了镜像的云服务器或本地容器),启动它非常简单。

打开你的终端,执行以下命令:

python /root/CLIP-ViT-H-14-laion2B-s32B-b79K_repackaged/app.py

你会看到类似下面的输出,说明服务正在启动,并加载模型:

Loading model CLIP-ViT-H-14-laion2B-s32B-b79K... Model loaded successfully. Running on local URL: http://0.0.0.0:7860

关键信息:服务运行在7860端口。记住这个端口号。

2.3 验证服务是否正常

服务启动后,我们最好先验证一下它是否工作正常。

  1. 访问Web界面: 打开你的浏览器,输入http://你的服务器IP地址:7860。你应该能看到一个上传图片的界面。上传一张图片试试,看看它能否成功显示提取的特征向量。这能最直观地确认服务是“活”的。

  2. 测试API接口(更重要的验证): Web界面是给人用的,API是给程序用的。我们通过命令行工具curl来测试一下核心的图片编码API。 打开另一个终端窗口,执行以下命令(请将[YOUR_IMAGE_URL]替换成一张网络上可访问的图片地址,例如https://example.com/test.jpg,将[YOUR_HOST]替换为你的服务器IP或域名):

    curl -X POST “http://[YOUR_HOST]:7860/encode_image” \ -H “Content-Type: application/json” \ -d ‘{“image_url”: “[YOUR_IMAGE_URL]”}’

    如果一切正常,你会收到一个JSON格式的响应,里面包含一个很长的数字列表(1280维的向量),这就是图片的特征。

    如果测试失败:检查服务是否真的在运行、端口是否正确、网络是否通畅、图片URL是否有效。

至此,我们的CLIP图像编码服务就已经在后台稳定运行了,它正等待着被我们的LangChain应用调用。接下来,我们进入核心的集成环节。

3. 核心集成:让LangChain调用CLIP

现在,我们有了一个提供图片“指纹”生成服务的“工厂”(CLIP服务)。接下来,我们要在LangChain这个“自动化流水线”上,新建一个“工位”,专门负责把图片送进这个工厂,并把产出的“指纹”拿回来。

在LangChain的体系中,这个过程需要通过一个自定义的Embeddings类来实现。Embeddings类是LangChain用于将文本(或其它数据)转换为向量(即嵌入)的抽象。我们要为图片创建一个。

3.1 创建自定义的图片嵌入类

我们将创建一个名为CLIPImageEmbeddings的类。把它保存为一个独立的Python文件,比如clip_embeddings.py

import requests from typing import List from langchain.embeddings.base import Embeddings from PIL import Image import io class CLIPImageEmbeddings(Embeddings): """一个自定义的Embeddings类,用于通过CLIP服务获取图片的向量表示。""" def __init__(self, base_url: str = “http://localhost:7860”): # 初始化,设置CLIP服务的API地址 self.base_url = base_url self.encode_url = f“{base_url}/encode_image” def _encode_image(self, image_path: str) -> List[float]: """内部方法:调用CLIP服务API,编码单张图片。""" # 准备请求数据,这里我们假设服务支持本地文件路径或URL # 根据你的CLIP服务API设计调整。这里示例是发送图片URL。 # 如果你的服务接收base64或文件上传,需要修改此部分。 data = {“image_url”: image_path} # 另一种常见方式是直接读取图片文件并传输,这里假设服务端支持从URL读取 # 对于本地文件,可能需要先上传到可访问的地址或修改服务端API。 try: response = requests.post(self.encode_url, json=data, timeout=30) response.raise_for_status() # 如果状态码不是200,抛出异常 result = response.json() # 假设API返回格式为 {“embedding”: [ ... ] } return result.get(“embedding”, []) except requests.exceptions.RequestException as e: print(f“调用CLIP API失败: {e}”) # 在实际生产中,这里应该记录日志并抛出更明确的异常 return [] def embed_documents(self, texts: List[str]) -> List[List[float]]: """LangChain标准接口:嵌入文档(文本)。本项目不用于文本,可抛出异常或返回空。""" raise NotImplementedError(“CLIPImageEmbeddings 仅支持图片嵌入,不支持文本。”) def embed_query(self, text: str) -> List[float]: """LangChain标准接口:嵌入查询(文本)。本项目不用于文本,可抛出异常或返回空。""" raise NotImplementedError(“CLIPImageEmbeddings 仅支持图片嵌入,不支持文本。”) def embed_images(self, image_paths: List[str]) -> List[List[float]]: """自定义方法:嵌入多张图片。这是我们的核心功能。""" embeddings = [] for path in image_paths: emb = self._encode_image(path) if emb: # 只添加成功的嵌入 embeddings.append(emb) return embeddings

代码解读

  1. 我们继承了LangChainEmbeddings基类。
  2. __init__方法初始化了CLIP服务的API地址。
  3. _encode_image是私有方法,负责与我们的CLIP服务通信,发送图片路径(URL),并接收返回的1280维向量。
  4. embed_documentsembed_query是LangChain要求的标准接口,但我们这个类只处理图片,所以直接抛出异常。这明确了它的职责。
  5. embed_images是我们自定义的核心方法,它接收一个图片路径列表,并返回对应的向量列表。

注意:上面的代码假设你的CLIP服务API接收一个image_url参数。你需要根据你实际部署的服务的API文档来调整_encode_image方法中的请求格式(例如,可能是文件上传multipart/form-data,或接收base64编码)。

3.2 测试图片嵌入功能

在继续构建知识库之前,我们先写个小脚本测试一下这个类是否工作正常。创建一个test_embedding.py文件。

from clip_embeddings import CLIPImageEmbeddings # 初始化嵌入器,确保base_url指向你正在运行的CLIP服务 embedder = CLIPImageEmbeddings(base_url=“http://localhost:7860”) # 修改为你的实际地址 # 准备一张测试图片的路径(这里用网络图片URL示例) test_image_url = “https://upload.wikimedia.org/wikipedia/commons/thumb/4/4d/Cat_November_2010-1a.jpg/800px-Cat_November_2010-1a.jpg” try: # 嵌入单张图片 embeddings = embedder.embed_images([test_image_url]) if embeddings: print(f“嵌入成功!向量维度: {len(embeddings[0])}”) print(f“向量前10个值: {embeddings[0][:10]}”) # 打印前10个值看看 else: print(“嵌入失败,未获取到向量。”) except Exception as e: print(f“测试过程中发生错误: {e}”)

运行这个测试脚本。如果看到输出了1280维的向量,恭喜你!LangChain已经成功通过你写的“工位”,从CLIP“工厂”拿到了图片的“数字指纹”。最关键的一步已经完成。

4. 构建多模态RAG知识库

有了图片嵌入器,我们就可以开始搭建整个RAG系统了。RAG的核心流程是“检索-增强-生成”。对于多模态,我们的知识库需要存储两种数据:文本片段及其向量,以及图片路径及其向量

4.1 设计知识库数据结构

我们需要一个向量数据库来存储和检索这些向量。这里以Chroma为例,因为它简单易用且与LangChain集成良好。当然,你也可以选择Weaviate,Pinecone等。

我们的知识库将包含两个独立的“集合”或“表”:

  1. 文本集合:存储文本文档及其文本嵌入(可以用OpenAI的text-embedding-ada-002或开源的BGE等模型)。
  2. 图片集合:存储图片路径(或唯一标识符)及其通过CLIPImageEmbeddings得到的图片嵌入。

4.2 创建并填充知识库

我们编写一个构建脚本build_knowledge_base.py

import os from langchain.vectorstores import Chroma from langchain.embeddings import OpenAIEmbeddings # 用于文本 from clip_embeddings import CLIPImageEmbeddings # 用于图片 from langchain.schema import Document from langchain.document_loaders import TextLoader, DirectoryLoader # 示例用文本加载器 # 1. 初始化嵌入模型 text_embedder = OpenAIEmbeddings() # 需要设置OPENAI_API_KEY环境变量 image_embedder = CLIPImageEmbeddings(base_url=“http://localhost:7860”) # 2. 准备数据 # 假设你的文本数据在 `./data/texts` 目录下,图片在 `./data/images` 目录下 text_data_dir = “./data/texts” image_data_dir = “./data/images” # 加载文本文档 text_documents = [] if os.path.exists(text_data_dir): loader = DirectoryLoader(text_data_dir, glob=“**/*.txt”, loader_cls=TextLoader) text_documents = loader.load() # 为每个文档添加来源类型元数据 for doc in text_documents: doc.metadata[“type”] = “text” print(f“已加载 {len(text_documents)} 个文本文档。”) # 准备图片“文档”(这里我们将图片路径视为文档内容) image_documents = [] if os.path.exists(image_data_dir): # 获取所有图片文件(示例支持jpg, png) image_extensions = [‘*.jpg’, ‘*.jpeg’, ‘*.png’, ‘*.bmp’, ‘*.gif’] image_paths = [] for ext in image_extensions: image_paths.extend([os.path.join(root, name) for root, dirs, files in os.walk(image_data_dir) for name in files if name.lower().endswith(ext.replace(‘*’, ‘’))]) for img_path in image_paths: # 创建一个Document对象,page_content可以是图片路径或描述,metadata记录类型和路径 doc = Document( page_content=img_path, # 或者你可以用一些工具自动生成图片描述 metadata={“type”: “image”, “source”: img_path} ) image_documents.append(doc) print(f“已加载 {len(image_documents)} 张图片。”) # 3. 创建并持久化向量库 persist_directory = “./chroma_db” # 创建文本向量库 if text_documents: text_vectordb = Chroma.from_documents( documents=text_documents, embedding=text_embedder, persist_directory=os.path.join(persist_directory, “text_collection”), collection_name=“text_collection” ) text_vectordb.persist() print(“文本向量库构建完成。”) # 创建图片向量库(关键步骤) if image_documents: # 首先,获取所有图片的嵌入向量 print(“开始提取图片特征向量,这可能需要一些时间...“) image_sources = [doc.metadata[“source”] for doc in image_documents] image_embeddings = image_embedder.embed_images(image_sources) # 确保嵌入向量数量与图片数量一致 valid_docs = [] valid_embeddings = [] for doc, emb in zip(image_documents, image_embeddings): if emb: # 只保留成功获取到嵌入的图片 valid_docs.append(doc) valid_embeddings.append(emb) if valid_docs: # Chroma 的 from_documents 需要传入embedding函数,但我们已经有向量了。 # 我们可以使用 `add_embeddings` 方法,或者用 `from_embeddings`。 # 这里使用 from_embeddings 更直接。 image_vectordb = Chroma.from_embeddings( text_embeddings=list(zip([doc.page_content for doc in valid_docs], valid_embeddings)), embedding=image_embedder, # 这里仍需传入embedding实例,但实际不会用它计算 persist_directory=os.path.join(persist_directory, “image_collection”), collection_name=“image_collection”, metadatas=[doc.metadata for doc in valid_docs] ) image_vectordb.persist() print(f”图片向量库构建完成,成功处理 {len(valid_docs)} 张图片。”) else: print(“未能成功提取任何图片的特征向量。”) else: print(“未找到图片数据。”) print(“多模态知识库构建完成!”)

这个脚本完成了以下工作:

  1. 分别初始化了文本和图片的嵌入模型。
  2. 从指定目录加载文本文件和图片文件。
  3. 使用文本嵌入模型为文本生成向量,并存入Chroma的一个集合(text_collection)。
  4. 使用我们自定义的CLIPImageEmbeddings为每张图片生成向量,并存入Chroma的另一个集合(image_collection)。

运行这个脚本,你的多模态知识库就构建好了。所有向量都保存在本地的./chroma_db目录下。

5. 实现多模态检索与问答

知识库建好了,最后一步就是让它“活”起来,能够响应用户的查询。用户可能用文字提问,也可能上传一张图片来提问。

5.1 创建检索与生成链

我们创建一个multimodal_rag.py文件来实现完整的问答流程。

from langchain.vectorstores import Chroma from langchain.embeddings import OpenAIEmbeddings from clip_embeddings import CLIPImageEmbeddings from langchain.chat_models import ChatOpenAI # 用于生成最终答案 from langchain.chains import RetrievalQA from langchain.prompts import PromptTemplate import requests from PIL import Image import io class MultimodalRAGSystem: def __init__(self, persist_dir=“./chroma_db”): # 加载已存在的向量数据库 self.text_vectordb = Chroma( persist_directory=f“{persist_dir}/text_collection”, embedding_function=OpenAIEmbeddings(), collection_name=“text_collection” ) self.image_vectordb = Chroma( persist_directory=f“{persist_dir}/image_collection”, embedding_function=CLIPImageEmbeddings(base_url=“http://localhost:7860”), # 注意这里 collection_name=“image_collection” ) # 初始化大语言模型(用于生成答案) self.llm = ChatOpenAI(model_name=“gpt-4”, temperature=0) # 为文本检索链设置提示模板 text_qa_prompt = PromptTemplate( input_variables=[“context”, “question”], template=“”“你是一个专业的助手,请根据以下上下文信息回答问题。如果上下文信息不足以回答问题,请如实说明。 上下文:{context} 问题:{question} 答案:”“” ) self.text_qa_chain = RetrievalQA.from_chain_type( llm=self.llm, chain_type=“stuff”, retriever=self.text_vectordb.as_retriever(search_kwargs={“k”: 3}), # 检索3个相关文本片段 chain_type_kwargs={“prompt”: text_qa_prompt} ) def query_with_text(self, question: str): ”“”用文本问题进行查询,返回文本答案和相关图片。”“” print(f“用户提问: {question}”) # 1. 从文本库检索相关文本信息 text_answer = self.text_qa_chain.run(question) print(f“基于文本的答案: {text_answer}”) # 2. 将问题本身作为“查询”,从图片库检索相关图片 # 注意:这里用文本问题去搜图片,依赖于CLIP的跨模态能力。 # 我们需要将问题文本转换为图片向量空间中的“查询向量”。 # 但我们的CLIP服务目前只提供了图片编码API。一个变通方法是: # 假设我们有一些代表常见概念的图片,或者我们无法直接进行“文搜图”。 # 更高级的实现需要服务端也暴露文本编码API。 # 这里我们简化处理:如果问题中包含明显的物体名词,我们可以尝试用这些名词去匹配图片元数据(如果有的话)。 # 这是一个待完善的环节。 print(“提示:高级‘文搜图’功能需要CLIP文本编码API支持。”) # 3. 返回结果 return { “text_answer”: text_answer, “related_images”: [] # 暂时返回空,或实现基于元数据的简单过滤 } def query_with_image(self, image_path: str, question: str = “描述这张图片”): ”“”用图片进行查询,返回相关文本和相似图片。”“” print(f“用户上传图片: {image_path}, 附带问题: {question}”) # 1. 从图片库检索相似图片(以图搜图) # 首先获取查询图片的向量 image_embedder = CLIPImageEmbeddings(base_url=“http://localhost:7860”) query_embedding = image_embedder.embed_images([image_path]) if not query_embedding: return {“error”: “无法处理上传的图片。”} # 在图片库中进行相似度搜索 similar_images = self.image_vectordb.similarity_search_by_vector( embedding=query_embedding[0], k=3 # 返回3张最相似的图片 ) print(f“找到 {len(similar_images)} 张相似图片:”) for img_doc in similar_images: print(f” - {img_doc.metadata.get(‘source’, ‘N/A’)}”) # 2. 根据检索到的图片,关联查找相关文本信息 # 我们可以用相似图片的元数据(如文件名、路径)中的关键词,去文本库中检索。 # 这里是一个简化示例:提取第一张相似图片的文件名作为关键词 related_texts = [] if similar_images: sample_image_source = similar_images[0].metadata.get(“source”, “”) # 假设文件名包含描述性关键词(例如 `cat_sunny_day.jpg`) import re # 简单地从文件名中提取单词(去掉扩展名和常见分隔符) filename_keywords = re.sub(r‘[._-]’, ‘ ‘, os.path.basename(sample_image_source).split(‘.’)[0]).split() if filename_keywords: # 用这些关键词构造一个查询去文本库搜索 keyword_query = ‘ ‘.join(filename_keywords[:3]) # 取前三个关键词 print(f“使用关键词 ‘{keyword_query}’ 检索相关文本...”) related_text_docs = self.text_vectordb.similarity_search(keyword_query, k=2) related_texts = [doc.page_content for doc in related_text_docs] # 3. 将检索到的文本和图片信息组合,让LLM生成一个综合回答 context_for_llm = f“”” 用户上传了一张图片,并询问:“{question}”。 系统找到了以下与图片相关的信息: - 相似图片:{ [img.metadata.get(‘source’, ‘’) for img in similar_images] } - 相关文本片段:{‘ ‘.join(related_texts) if related_texts else ‘暂无相关文本信息。’} “”” final_answer = self.llm.predict(context_for_llm + “\n请根据以上信息,生成一个友好、全面的回答。”) print(f“综合答案: {final_answer}”) return { “similar_images”: [img.metadata.get(“source”) for img in similar_images], “related_texts”: related_texts, “final_answer”: final_answer } # 使用示例 if __name__ == “__main__”: rag_system = MultimodalRAGSystem() # 示例1:文本查询 print(“=== 示例1:文本查询 ===”) result1 = rag_system.query_with_text(“我们公司的主要产品是什么?”) print(result1[“text_answer”]) print(“\n=== 示例2:图片查询 ===”) # 假设有一张测试图片路径 test_img_path = “./data/images/example_product.jpg” if os.path.exists(test_img_path): result2 = rag_system.query_with_image(test_img_path, “这张图片里的产品有什么特点?”) print(result2[“final_answer”]) else: print(f“测试图片不存在: {test_img_path}”)

5.2 系统工作流程解析

这个MultimodalRAGSystem类封装了整个流程:

  1. 初始化:加载之前构建好的文本和图片向量库,并初始化一个大语言模型(如GPT-4)用于生成最终答案。
  2. 文本查询 (query_with_text)
    • 用户输入一个问题。
    • 系统从文本向量库中检索出最相关的几段文本。
    • 将这些文本作为“上下文”,连同问题一起发送给LLM,生成一个文本答案。
    • (高级功能):理论上,可以用同样的问题去图片向量库中检索相关图片(文搜图),但这需要CLIP服务提供将文本编码为向量的API。我们的服务目前只提供了图片编码。这是一个可以扩展的方向。
  3. 图片查询 (query_with_image)
    • 用户上传一张图片,并可能附带一个问题(如“描述这张图”或“这个产品用什么材料?”)。
    • 系统使用我们的CLIPImageEmbeddings将这张图片转换为向量。
    • 用这个向量在图片向量库中进行相似度搜索,找到最相似的几张图片(以图搜图)。
    • 然后,系统尝试从找到的相似图片中提取信息(例如文件名中的关键词),并用这些关键词去文本向量库中检索相关的文本描述。
    • 最后,将检索到的所有信息(相似图片列表、相关文本)组合成一段上下文,发送给LLM,让它生成一个结合了图文信息的综合答案。

6. 总结与展望

至此,我们已经完成了一个完整的、可运行的多模态RAG知识库原型。让我们回顾一下核心步骤和学到的关键点:

  1. 服务化:我们将CLIP ViT-H-14这个复杂的模型封装成了一个提供标准API的独立服务,这是工程化的第一步,实现了能力解耦和复用。
  2. 自定义集成:通过创建CLIPImageEmbeddings类,我们成功地将自定义的图片编码能力接入到LangChain的生态中。这是连接专有模型与通用框架的关键桥梁。
  3. 多模态数据管理:我们设计了一个包含文本和图片两个独立向量集合的知识库架构。这种分离存储、联合检索的思路,是处理异构数据的一种有效方式。
  4. 混合检索逻辑:我们实现了初步的“文-文检索”和“图-图检索”,并探索了“图-文关联检索”。真正的“文-图跨模态检索”需要模型提供双向编码能力,这是我们未来可以优化的方向。

6.1 下一步可以做什么?

这个原型已经具备了强大的潜力,你可以从以下几个方向深化它:

  • 完善CLIP服务:为你的CLIP服务增加文本编码API,从而实现真正的、高效的“用文字搜图片”功能。
  • 优化检索策略:实现更智能的混合检索。例如,同时用文字问题检索文本和图片(如果支持文搜图),然后将所有结果进行重排序(Rerank),选出最相关的信息送给LLM。
  • 丰富数据源:接入更多类型的文档加载器(PDF、PPT、Word、网页),并探索为图片自动生成文字描述(使用BLIP、LLaVA等模型),然后将描述文本也存入数据库,作为图文关联的桥梁。
  • 构建前端界面:使用Gradio、Streamlit或前端框架,打造一个用户友好的Web界面,让用户可以拖拽上传图片、输入问题,并直观地看到检索到的图片和生成的答案。
  • 部署与优化:考虑将整个系统容器化,用Docker Compose管理CLIP服务、向量数据库和Web应用,并部署到云服务器上。

通过本教程,你不仅学会了如何集成CLIP与LangChain,更重要的是掌握了一种思路:将前沿的AI模型能力通过标准化接口暴露出来,再通过灵活的框架将其组合成解决实际问题的应用。这种能力,正是构建下一代智能系统的关键。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

http://www.jsqmd.com/news/489028/

相关文章:

  • Linux基础操作——学习记录
  • 支付领域 - 资损问题
  • GPEN面部增强系统保姆级教程:从零开始玩转老照片修复
  • Phi-3 Forest Lab部署教程:解决Transformers底层兼容问题的详细步骤与代码实例
  • LiuJuan Z-Image Generator快速部署:NVIDIA Container Toolkit一键适配
  • LingBot-Depth保姆级教学:日志排查、端口冲突解决与容器健康检查
  • 计算机软件资格考试—流程图部分
  • ...........
  • ollama部署QwQ-32B实操手册:多线程并发推理与吞吐量优化
  • 打造专业模板:WPS文字型窗体域实战指南
  • 如何解决 CAS 的 ABA 问题:从版本号机制到 AtomicStampedReference 深度解析
  • Clawdbot汉化版应用案例:律所企业微信合同条款审查+风险提示自动化
  • 正念80%的效果来自心态:非评判、好奇心、自我友善,三种态度重塑你的生活
  • Kimi LeetCode 552.学生出勒记录|| public int checkRecord(int n)
  • c语言-文件读写
  • WPS动态序号填充四种方法,告别手动调整烦恼
  • SOONet效果展示:体育视频中‘发球→扣杀→得分’战术链自动识别与标记
  • 2026年热门的强力工业风扇厂家推荐:永磁工业风扇可靠供应商推荐 - 品牌宣传支持者
  • 【JDK17-HttpClient】 Selector/Channel 的NIO实现细节?与Netty的NIO实现有何异同?
  • 【C++】模版初阶
  • Java对象头:深入理解对象存储的核心机制
  • 【JDK17-HttpClient】零拷贝(Zero-Copy) 支持吗?大文件传输的内存优化机制?
  • 2026年评价高的发酵饲料设备厂家推荐:大型发酵饲料设备/养殖用发酵饲料设备/全自动发酵饲料设备制造厂家推荐 - 品牌宣传支持者
  • Openclaw本地化部署操作手册
  • 2025_NIPS_IR-OptSet: An Optimization-Sensitive Dataset for Advancing LLM-Based IR Optimizer
  • 《深入掌握PostgreSQL数据库》 - 专栏介绍和目录
  • 纳米AI LeetCode 564.寻找最近的回文数 public String nearestPalindromic(String n)
  • OpenClaw 超级 AI 实战专栏【模型推理与实战】(五)推理参数调优:精度、速度、显存平衡
  • 2026年口碑好的小型发酵饲料设备工厂推荐:固态发酵饲料设备/智能发酵饲料设备工厂直供推荐 - 品牌宣传支持者
  • WuliArt Qwen-Image Turbo避坑指南:解决黑图、显存不足等常见问题