Quivr 基于GPT和開源LLMs構建本地知識庫 (更新篇)

一、前言

自從大模型被炒的越來越火之后,似乎國內涌現出很多希望基于大模型構建本地知識庫的需求,大概在5月底的時候,當時Quivr發布了第一個0.0.1版本,第一個版本僅僅只是使用LangChain技術結合OpenAI的GPT模型實現了一個最基本的架子,功能并不夠完善,但可以研究研究思路,當時 Quivr 通過借助于GPT的模型能力,選擇Supabase構建向量數據庫來實現個人知識庫還算是一個不錯的選擇,自此一直有在關注 Quivr 的進展,基本上Quivr的更新頻率還是比較高的,5月底寫了一篇關于如何在本地基于Quivr構建知識庫的文章之后,陸陸續續基本上都有一些朋友私聊詢問有關Quivr構建的一些問題,也有一些對于Quivr未來功能規劃方向的建議和期望,如果Quivr發展的比較成熟,對于個人或者中小企業或許也是一個低成本的選擇。

隨著這兩個多月的更新,Quivr已經陸續發布了五十多個版本,不管是對原來功能的改進,代碼的重構,還是擴展了很多新功能,都讓Quivr看起來沒有原來那么弱小了,基礎的功能基本上也覆蓋到了。感興趣的可以嘗試一下。

對于原來發布的文章和視頻,有感興趣的可以從下面的鏈接進去,因為Quivr一直在更新,在部署方面可能有些許變化,如果想部署最新版本的Quivr,可以直接看這篇最新的升級篇即可。

[文章]Quivr 基于Supabase構建本地知識庫

[視頻]Quivr 基于Supabase構建本地知識庫

二、功能特性

2.1、大腦擴展能力

從單個賬號只支持一個大腦,到現在可以支持多個大腦(具體數量可以配置,默認為5個),這樣部署一套Quivr系統就可以創建多個大腦來對知識庫進行分開維護,減少數據的檢索范圍和數據權限隔離。

用戶可以根據偏好來自定義知識庫,比如針對產品的智能客服、針對交付的Q&A助理、產品經理助手等等。

2.2、大腦權限控制

支持對單個知識庫根據[瀏覽]、[編輯]、[所有者]三個角色來設置對應的訪問權限,同時也支持通過鏈接和郵件的方式分享個人大腦給其他用戶。

這樣就可以很方便的實現個人私有知識庫,或者是公司團隊共享的知識庫,而避免了以前每個用戶都需要重復上傳相同的知識,導致Key的浪費和知識的冗余。

2.3、LLM擴展能力

原來的版本只支持集成GPT和Claude模型,現在擴展了對本地開源模型的支持,如GPT4All,后續還將支持更多的開源模型。

2.4、開放API接口

Quivr采用前后端分離的獨立架構,Quivr 使用 FastAPI 為后端提供 RESTful API,后端服務可以獨立使用,不需要前端應用程序,我們的第三方應用也可以很方便的通過API接口集成Quivr大腦的我們自己的產品中

三、基礎環境準備

3.1、先決條件

為了減少部署過程中不必要的麻煩,建議操作系統選擇Ubuntu 22或更高版本,至于服務器只要能正常訪問OpenAI的接口都可以,我在GCP/AWS/阿里云上都安裝過,主要解決網絡問題,選對服務器所在區域即可。

系統內存:如果只是個人用來部署玩一下,建議不少于1GB,2GB比較合適,如果想用于正式環境,則需根據具體的業務訪問量配置。

系統硬盤:僅僅部署演示,建議不少于30GB。

接下來將演示在 Ubuntu 22 版本上快速部署Quivr來構建本地知識庫系統。

3.2、安裝Docker & Docker-Compose

首先安裝 Docker 和 Docker Compose ,可以按照以下步驟進行操作:

1、更新系統軟件包列表:

sudo apt update

2、安裝Docker依賴的軟件包:

sudo apt install apt-transport-https ca-certificates curl software-properties-common

3、添加Docker官方的GPG密鑰:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

4、添加Docker的軟件源:

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

5、更新軟件包列表:

sudo apt update

6、安裝Docker Engine:

sudo apt install docker-ce docker-ce-cli containerd.io

7、驗證Docker是否正確安裝:

sudo docker run hello-world

8、安裝Docker Compose:

sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

9、添加執行權限:

sudo chmod +x /usr/local/bin/docker-compose

10、驗證Docker Compose是否正確安裝:

docker-compose --version

現在,您已經成功在Ubuntu上安裝了Docker和Docker Compose。您可以使用這些命令來管理和運行容器化的應用程序。

錯誤:failed to update store for object type *libnetwork.endpointCnt: Key not found in store

Restart docker deamon would fix it.For ubuntu:sudo service docker restart

四、創建Supabase項目

Supabase是一個開源的Firebase替代品。使用 Postgres 數據庫、身份驗證、即時 API、邊緣函數、實時訂閱、存儲和向量嵌入。一個免費賬戶可以創建2個項目。

1、注冊賬戶

前往https://supabase.com/可以注冊免費賬戶。

2、創建項目

????

3、配置網站URL和重定向地址

主要用于密碼重置和電子郵件重定向跳轉鏈接。地址為系統前端訪問地址:http://ip:3000

?

?
??

五、部署Quivr應用

5.1、克隆存儲庫

git clone https://github.com/StanGirard/Quivr.git && cd Quivr
  • 可以使用 ls -alh 命令查看所有文件(包含隱藏文件)

一般Quivr每周都會在主分支更新新的內容,會存在一定未知的bug,建議選擇一個最新的release穩定版本進行部署

?https://sundun-rdcenter.feishu.cn/space/api/box/stream/download/asynccode/?code=MjU3ZWFmMzU1ODYxNWRlMjExNGE2OGU3Nzg0YTdjOTJfREkzaWFKa0JSRDdHVkNqOTdmekl2VVdWd1UxaURLR1pfVG9rZW46R21PRGI1N0Rsb1R2ZHh4WFJDdmNOQkdobnIwXzE2OTIxNTI0OTc6MTY5MjE1NjA5N19WNA?

5.2、復制.XXXXX_env文件

新版本后端代碼重構了,新的配置文件注意在backend/core/目錄下面。

cp .backend_env.example backend/core/.env
cp .frontend_env.example frontend/.env

5.3、更新frontend/.env文件

NEXT_PUBLIC_ENV=local
NEXT_PUBLIC_BACKEND_URL=http://你的IP:5050/
NEXT_PUBLIC_SUPABASE_URL=your supabase project url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your supabase api key
NEXT_PUBLIC_JUNE_API_KEY=your june api key

請注意,如果Quivr部署在本機電腦,backend_url直接使用localhost,如果Quivr部署在本地服務器或者云服務器則需要將后端URL修改為你服務器的實際的IP地址。(很多人會忽略這個配置!)

關于NEXT_PUBLIC_JUNE_API_KEY屬性的配置說明:

Quivr 集成了 June Analytics 提供的API接口,在集成了June Analytics 之后,你只需要在系統中配置正確的June API密鑰(即June key),然后June網站會自動開始收集和跟蹤系統的數據。

一旦數據開始被收集,你可以登錄到June Analytics的儀表板,并在其中查看和分析收集到的數據。June儀表板提供了一個用戶友好的界面,用于瀏覽各種報告、圖表和指標,以便你了解用戶行為、事件觸發和其他關鍵指標。

通過June儀表板,你可以探索不同的分析視圖,如用戶活動、事件追蹤、轉化率等。你可以根據時間范圍、特定用戶或自定義事件來過濾和細化數據,以獲取更具體的見解和洞察。

如果是正式上線的站點,可以按需選擇接入,默認可以不用考慮設置此參數,如果需要收集和分析網站的數據,可以去注冊June賬號,申請一個June Key

?5.4、更新backend/core/.env文件?

SUPABASE_URL=your supabase project url
SUPABASE_SERVICE_KEY=your supabase api key
PG_DATABASE_URL=notimplementedyet
OPENAI_API_KEY=your openai api key
ANTHROPIC_API_KEY=null
JWT_SECRET_KEY=your supabase jwt secret keyAUTHENTICATE=true
GOOGLE_APPLICATION_CREDENTIALS=<change-me>
GOOGLE_CLOUD_PROJECT=<change-me># 默認50M
MAX_BRAIN_SIZE=52428800. 
MAX_REQUESTS_NUMBER=2000
MAX_BRAIN_PER_USER=100# Private LLM Variables
PRIVATE=False
MODEL_PATH=./local_models/ggml-gpt4all-j-v1.3-groovy.bin# RESEND
RESEND_API_KEY=your resend api key
RESEND_EMAIL_ADDRESS=your resend email address

請注意,supabase_url在您的Supabase儀表板下的項目設置-> API中對應的Project URL,supabase_service_key在您的Supabase儀表板下的項目設置-> API中找到。使用“Project API keys”部分中找到的anon public鍵。您 JWT_SECRET_KEY可以在 Project Settings -> JWT Settings -> JWT Secret 下的 supabase 設置中找到。(注意ANTHROPIC_API_KEY可以不配置值,但key不能刪除,否則構建會失敗)

5.5、創建Supabase數據庫和表

通過Web界面(SQL編輯器->“New Query”)在Supabase數據庫上運行以下遷移腳本。

數據庫腳本地址:

https://github.com/StanGirard/quivr/blob/main/scripts/tables.sql

-- Create users table
CREATE TABLE IF NOT EXISTS users(user_id UUID REFERENCES auth.users (id),email TEXT,date TEXT,requests_count INT,PRIMARY KEY (user_id, date)
);-- Create chats table
CREATE TABLE IF NOT EXISTS chats(chat_id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,user_id UUID REFERENCES auth.users (id),creation_time TIMESTAMP DEFAULT current_timestamp,history JSONB,chat_name TEXT
);-- Create vector extension
CREATE EXTENSION IF NOT EXISTS vector;-- Create vectors table
CREATE TABLE IF NOT EXISTS vectors (id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,content TEXT,metadata JSONB,embedding VECTOR(1536)
);-- Create function to match vectors
CREATE OR REPLACE FUNCTION match_vectors(query_embedding VECTOR(1536), match_count INT, p_brain_id UUID)
RETURNS TABLE(id UUID,brain_id UUID,content TEXT,metadata JSONB,embedding VECTOR(1536),similarity FLOAT
) LANGUAGE plpgsql AS $$
#variable_conflict use_column
BEGINRETURN QUERYSELECTvectors.id,brains_vectors.brain_id,vectors.content,vectors.metadata,vectors.embedding,1 - (vectors.embedding <=> query_embedding) AS similarityFROMvectorsINNER JOINbrains_vectors ON vectors.id = brains_vectors.vector_idWHERE brains_vectors.brain_id = p_brain_idORDER BYvectors.embedding <=> query_embeddingLIMIT match_count;
END;
$$;-- Create stats table
CREATE TABLE IF NOT EXISTS stats (time TIMESTAMP,chat BOOLEAN,embedding BOOLEAN,details TEXT,metadata JSONB,id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY
);-- Create summaries table
CREATE TABLE IF NOT EXISTS summaries (id BIGSERIAL PRIMARY KEY,document_id UUID REFERENCES vectors(id),content TEXT,metadata JSONB,embedding VECTOR(1536)
);-- Create function to match summaries
CREATE OR REPLACE FUNCTION match_summaries(query_embedding VECTOR(1536), match_count INT, match_threshold FLOAT)
RETURNS TABLE(id BIGINT,document_id UUID,content TEXT,metadata JSONB,embedding VECTOR(1536),similarity FLOAT
) LANGUAGE plpgsql AS $$
#variable_conflict use_column
BEGINRETURN QUERYSELECTid,document_id,content,metadata,embedding,1 - (summaries.embedding <=> query_embedding) AS similarityFROMsummariesWHERE 1 - (summaries.embedding <=> query_embedding) > match_thresholdORDER BYsummaries.embedding <=> query_embeddingLIMIT match_count;
END;
$$;-- Create api_keys table
CREATE TABLE IF NOT EXISTS api_keys(key_id UUID DEFAULT gen_random_uuid() PRIMARY KEY,user_id UUID REFERENCES auth.users (id),api_key TEXT UNIQUE,creation_time TIMESTAMP DEFAULT current_timestamp,deleted_time TIMESTAMP,is_active BOOLEAN DEFAULT true
);--- Create prompts table
CREATE TABLE IF NOT EXISTS prompts (id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,title VARCHAR(255),content TEXT,status VARCHAR(255) DEFAULT 'private'
);--- Create brains table
CREATE TABLE IF NOT EXISTS brains (brain_id UUID DEFAULT gen_random_uuid() PRIMARY KEY,name TEXT NOT NULL,status TEXT,description TEXT,model TEXT,max_tokens INT,temperature FLOAT,openai_api_key TEXT,prompt_id UUID REFERENCES prompts(id)
);-- Create chat_history table
CREATE TABLE IF NOT EXISTS chat_history (message_id UUID DEFAULT uuid_generate_v4(),chat_id UUID REFERENCES chats(chat_id),user_message TEXT,assistant TEXT,message_time TIMESTAMP DEFAULT current_timestamp,PRIMARY KEY (chat_id, message_id),prompt_id UUID REFERENCES prompts(id),brain_id UUID REFERENCES brains(brain_id)
);-- Create brains X users table
CREATE TABLE IF NOT EXISTS brains_users (brain_id UUID,user_id UUID,rights VARCHAR(255),default_brain BOOLEAN DEFAULT false,PRIMARY KEY (brain_id, user_id),FOREIGN KEY (user_id) REFERENCES auth.users (id),FOREIGN KEY (brain_id) REFERENCES brains (brain_id)
);-- Create brains X vectors table
CREATE TABLE IF NOT EXISTS brains_vectors (brain_id UUID,vector_id UUID,file_sha1 TEXT,PRIMARY KEY (brain_id, vector_id),FOREIGN KEY (vector_id) REFERENCES vectors (id),FOREIGN KEY (brain_id) REFERENCES brains (brain_id)
);-- Create brains X vectors table
CREATE TABLE IF NOT EXISTS brain_subscription_invitations (brain_id UUID,email VARCHAR(255),rights VARCHAR(255),PRIMARY KEY (brain_id, email),FOREIGN KEY (brain_id) REFERENCES brains (brain_id)
);--- Create user_identity table
CREATE TABLE IF NOT EXISTS user_identity (user_id UUID PRIMARY KEY,openai_api_key VARCHAR(255)
);CREATE OR REPLACE FUNCTION public.get_user_email_by_user_id(user_id uuid)
RETURNS TABLE (email text)
SECURITY definer
AS $$
BEGINRETURN QUERY SELECT au.email::text FROM auth.users au WHERE au.id = user_id;
END;
$$ LANGUAGE plpgsql;CREATE OR REPLACE FUNCTION public.get_user_id_by_user_email(user_email text)
RETURNS TABLE (user_id uuid)
SECURITY DEFINER
AS $$
BEGINRETURN QUERY SELECT au.id::uuid FROM auth.users au WHERE au.email = user_email;
END;
$$ LANGUAGE plpgsql;CREATE TABLE IF NOT EXISTS migrations (name VARCHAR(255)  PRIMARY KEY,executed_at TIMESTAMPTZ DEFAULT current_timestamp
);INSERT INTO migrations (name) 
SELECT '20230809154300_add_prompt_id_brain_id_to_chat_history_table'
WHERE NOT EXISTS (SELECT 1 FROM migrations WHERE name = '20230809154300_add_prompt_id_brain_id_to_chat_history_table'
);

數據庫腳本執行完成后,在Table編輯器中可以看到已經創建完成的表。

5.6、設置yarn的超時時間

在前端容器構建依賴階段一般會比較慢,部分依賴可能由于網絡原因長時間無法完成會導致yarn連接超時,舊版本可以在/frontend/Dockerfile文件中修改yarn install部分的腳本,增加網絡超時參數,新版本已增加該參數可忽略此步驟。

RUN yarn install --network-timeout 1000000

5.7、構建并啟動Quivr?

docker compose -f docker-compose.yml up --build -d

Quivr構建完成啟動后如下圖所示:

六、訪問Quivr

部署完成后,直接訪問 http://ip:3000,第一次部署可以通過郵箱注冊賬號

6.1、添加新大腦

Quivr 有一個“大腦”的概念。它們是封閉的信息體,可用于為大型語言模型 (LLM) 提供上下文,以回答有關特定主題的問題。

LLM接受過各種各樣的數據培訓,但要回答有關特定主題的問題或用于圍繞特定主題進行推論,需要向他們提供該主題的上下文。Quivr 使用大腦作為提供上下文的直觀方式。

當在 Quivr 中選擇大腦時,LLM將僅獲得該大腦的上下文。這允許用戶為特定主題構建大腦,然后用它們來回答有關該主題的問題。未來 Quivr 將會有與其他用戶共享大腦的功能。

在Quivr新版本中,可以支持創新多個知識庫大腦,實現知識庫的內容檢索隔離,同時還支持對支持庫進行授權,只允許授權用戶才能訪問,也可以通過分享鏈接的方式共享知識庫。比幾個月前的版本功能更加完善。

1)、要使用大腦,只需從 Quivr 界面右上角標題中的“使用大腦”圖標中選擇菜單即可。

2)、我們可以通過單擊“創建大腦”按鈕來創建一個新的大腦。系統將提示您輸入大腦的名稱。你也可以使用賬戶生成的默認大腦。

3)、要切換到不同的大腦,只需單擊菜單中的大腦名稱并選擇您想要使用的大腦即可。

4)、如果你沒有選擇大腦,則你上傳的任何文檔都將添加到默認大腦中。

5)、在新建大腦知識庫界面中,可以設置使用的模型和模型相關參數,同時也可以針對每個知識庫大腦設置獨有的Prompt以及所使用的OpenAI API Key,不設置則默認讀取配置文件中配置的Key。

注意:如果在使用聊天功能時,需要從菜單中先選擇一個大腦才能使用聊天功能。

6.2、共享知識庫

在選擇大腦界面,我們點擊大腦后面的分享按鈕,通過URL或者發郵件的方式分享或者邀請其它用戶加入大腦,共享知識庫。

?

Quivr 中通過集成 Resend API,用于通過電子郵件邀請來處理共享大腦。

在 /backend/core/.env 文件中引入了兩個環境變量來配置發送郵件的功能:

  • RESENDAPIKEY:這是 Resend 為我們的應用程序提供的唯一 API 密鑰。它使我們能夠以安全的方式與 Resend 平臺進行通信。

  • RESENDEMAILADDRESS:這是我們通過重新發送發送電子郵件時用作發件人地址的電子郵件地址。

從環境變量中獲取 Resend API 密鑰和電子郵件地址后,我們使用它通過 resend.Emails.send 方法發送電子郵件。

6.2、上傳知識庫

新建完知識庫大腦后,就可以選擇對應的知識庫,上傳文檔構建向量數據了,支持文檔、音頻、視頻和網頁鏈接,所有文件最終都會抽取文件中的文本內容通過調用大模型的API構建向量數據。

?文件上傳完成后,會有如下提示信息

6.3、查詢知識庫

知識庫文檔構建完成后,就可以對當前選擇的知識庫大腦進行內容檢索了,這里我們以魯迅先生在日本留學的老師藤野先生為例來測試一下Quivr是否正確識別了知識庫文檔的內容。?

在沒學習專有知識之前,GPT模型不知道魯迅先生在日本學醫的老師是誰,一般會胡亂給出一個日本人的名字,而且多次詢問,人命還不一致。?在上傳完關于魯迅先生寫的《藤野先生》部分文章內容之后,我們再次詢問發現可以成功檢索正確的答案了。?

七、本地化LLM支持

Quivr 在0.0.46版本可以正式支持接入本地LLM大模型,目前只支持由 GPT4All 提供支持的私有 LLM 模型(其他開源模型即將推出),基本上與 PrivateGPT 項目提供的功能類似。意味著你的數據永遠存儲在本地。LLM 將下載到服務器并在本地對你的問題運行推理。

7.1、使用方法

  • /backend/core/.env 文件中將“private”屬性設置為 True。您還可以在 .env 文件中設置其他模型參數。

  • GPT4All 模型下載地址:https://gpt4all.io/models/ggml-gpt4all-j-v1.3-groovy.bin

將下載的 GPT4All 模型放在 /backend/local_models 文件夾中。

GPT4All 是一個開源軟件生態系統,允許任何人在日常硬件上訓練和部署強大定制的大型語言模型 (LLM)。 Nomic AI 負責監督對開源生態系統的貢獻,確保質量、安全性和可維護性。

GPT4All 軟件生態系統與以下 Transformer 架構兼容:

  • Falcon

  • LLaMA (including OpenLLaMA)

  • MPT (including Replit)

  • GPT-J

  • Replit - 基于 Replit Inc. 的 Replit 架構

  • StarCoder - 基于 BigCode 的 StarCoder 架構

具體支持的模型型號列表可以從 GPT4All 的網站上查看詳盡列表,或下載任何支持的模型。使用這些架構之一訓練的任何模型都可以量化,并使用所有 GPT4All 綁定在本地運行,并在聊天客戶端。您可以通過為 gpt4all 后端做出貢獻來添加新變體。

7.2、未來計劃

Quivr 計劃在本地私有化 LLM 功能中添加更多模型。使用 Hugging Face 的本地嵌入模型來減少對 OpenAI API 的依賴。未來還將添加在前端和 API 中使用私有 LLM 模型的功能。目前的版本只有部署后端才能使用。

八、Quivr路線圖

https://sundun-rdcenter.feishu.cn/space/api/box/stream/download/asynccode/?code=Y2VjODgzY2ViOTMyNzM3MzgyZTI4ODU2YWI5ZmFhZGJfY0FTZ1U1a09UVkR6Vld3QUdYSE0yVTNoamU2dXpWVjFfVG9rZW46Wk5SV2I3UlZ2b1YxSEp4RkJvdmNNc3ZwbmZjXzE2OTIxNTI0OTc6MTY5MjE1NjA5N19WNA?

九、References

  • Quivr GitHub

https://github.com/StanGirard/quivr

  • Quivr FastAPI

https://api.quivr.app/docs

  • Resend API

https://resend.com/overview

  • June Analytics

https://analytics.june.so/

  • GPT4All WebSite

https://gpt4all.io/index.html

  • GPT4All Models

https://gpt4all.io/models/ggml-gpt4all-j-v1.3-groovy.bin

  • GPT4All Supported Models

https://raw.githubusercontent.com/nomic-ai/gpt4all/main/gpt4all-chat/metadata/models.json

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39957.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39957.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39957.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

升級STM32電機PID速度閉環編程:從F1到F4的移植技巧與實例解析

引言&#xff1a; 在嵌入式系統開發中&#xff0c;STM32系列微控制器廣泛應用于各種應用領域。而對于直流有刷電機的控制&#xff0c;PID速度閉環是一種常用的控制方式。本文將以此為例&#xff0c;探討如何從STM32F1系列移植到STM32F4系列&#xff0c;并詳細介紹HAL庫在不同型…

Python學習筆記_基礎篇(十)_socket編程

本章內容 1、socket 2、IO多路復用 3、socketserver Socket socket起源于Unix&#xff0c;而Unix/Linux基本哲學之一就是“一切皆文件”&#xff0c;對于文件用【打開】【讀寫】【關閉】模式來操作。socket就是該模式的一個實現&#xff0c;socket即是一種特殊的文件&…

spring boot 簡單整合 Redis

1.添加依賴<!-- redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- commons-pool2 --><dependency><groupId>org.ap…

Linux安裝Docker

一、Docker系統版本介紹 Docker 是一個開源的應用容器引擎&#xff0c;讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中&#xff0c;然后發布到任何流行的 Linux 或 Windows 操作系統的機器上&#xff0c;也可以實現虛擬化。 容器是完全使用沙箱機制&#xff0c;相…

誠邁科技榮膺小米“最佳供應商獎”

近日&#xff0c;誠邁科技受邀參加小米戰略合作伙伴HBR總結會。誠邁科技以盡職盡責的合作態度、精益求精的交付質量榮膺小米公司頒發的最佳供應商獎&#xff0c;其性能測試團隊榮獲優秀團隊獎。 誠邁科技與小米在手機終端方向一直保持著密切的合作關系&#xff0c;涉及系統框架…

centOS 快速安裝和配置 NVIDIA docker Container Toolkit

要在 CentOS 上正確安裝和配置 NVIDIA Container Toolkit&#xff0c;您可以按照以下步驟進行操作&#xff0c;如果1和2都已經完成&#xff0c;可以直接進行第3步NVIDIA Container Toolkit安裝配置。 1. 安裝 NVIDIA GPU 驅動程序&#xff1a; 您可以從 NVIDIA 官方網站下載適…

【Java基礎】Java對象的生命周期

【Java基礎】Java對象的生命周期 一、概述 一個類通過編譯器將一個Java文件編譯為Class字節碼文件&#xff0c;然后通過JVM中的解釋器編譯成不同操作系統的機器碼。雖然操作系統不同&#xff0c;但是基于解釋器的虛擬機是相同的。java類的生命周期就是指一個class文件加載到類…

Ubuntu安裝MySQL Server提示Depends: mysql-server-5.5怎么解決

在 Ubuntu 安裝 MySQL Server 時出現 Depends: mysql-server-5.5 的錯誤通常是因為系統中沒有找到所需的軟件包版本。這可能是因為軟件包源中沒有對應的版本或者軟件包版本沖突等原因。解決這個問題的方法如下&#xff1a; 更新軟件包列表&#xff1a; 在終端中運行以下命令&a…

python控制obs實現無縫切換場景!obs-websocket-py

前言 最近一直在研究孿生數字人wav2lip。目前成果可直接輸入高清嘴型&#xff0c;2070顯卡1分鐘音頻2.6分鐘輸出。在直播邏輯上可以做到1比1.3這樣&#xff0c;所以現在開始研究直播。在邏輯上涉及到了無縫切換&#xff0c;看到csdn上有一篇文章還要vip解鎖。。。那自己研究吧…

臨時用工小程序:一款便捷的用工管理軟件

隨著企業對人力資源需求的不斷增長&#xff0c;臨時用工需求也日益旺盛。為了滿足這一需求&#xff0c;我們研發了一款名為“臨時用工小程序”的軟件系統&#xff0c;旨在幫助企業實現臨時用工的高效管理。 一、技術棧介紹 后端技術棧 本系統采用Java語言作為開發語言&#…

尚硅谷MySQL筆記 3-9

我不會記錄的特別詳細 大體框架 基本的Select語句運算符排序與分頁多表查詢單行函數聚合函數子查詢 第三章 基本的SELECT語句 SQL分類 這個分類有很多種&#xff0c;大致了解下即可 DDL&#xff08;Data Definition Languages、數據定義語言&#xff09;&#xff0c;定義了…

項目難點:解決IOS調用起軟鍵盤之后頁面樣式布局錯亂問題

需求背景 &#xff1a; 開發了一個問卷系統重構項目&#xff0c;剛開始開發的為 PC 端&#xff0c;其中最頭疼的一點無非就是 IE 瀏覽器的兼容適配性問題&#xff1b; 再之后項目經理要求開發移動端&#xff0c;簡單的說就是寫 H5 頁面&#xff0c;到時候會內嵌在 App 應用、辦…

multiple definition of......first defined here

一、背景 環境&#xff1a; 銀河麒麟–ARM–GCC7.4.0 寫了一個動態庫&#xff0c;依賴opencv和freeImage等第三方庫&#xff0c;用cmake進行編譯。原本在centos6-x86-gcc7.5.0上面進行編譯非常的順利&#xff0c;但是拿到麒麟arm上面編譯就提示了這個錯誤&#xff1a;這個報錯…

Python conda命令

Windows下 Anaconda Prompt 這個東西就是用來管理Anaconda的&#xff0c;使用的是conda這樣的一種命令 在Linux中&#xff0c;可以直接在終端中輸入conda 命令 可以使用conda命令創建新的python環境&#xff08;python版本&#xff0c;包&#xff09;&#xff0c;新的環境與原…

Ruby軟件外包開發語言特點

Ruby 是一種動態、開放源代碼的編程語言&#xff0c;它注重簡潔性和開發人員的幸福感。在許多方面都具有優點&#xff0c;但由于其動態類型和解釋執行的特性&#xff0c;它可能不適合某些對性能和類型安全性要求較高的場景。下面和大家分享 Ruby 語言的一些主要特點以及適用的場…

【C語言】動態通訊錄 -- 詳解

?前言 前面詳細介紹了靜態版通訊錄【C語言】靜態通訊錄 -- 詳解_炫酷的伊莉娜的博客-CSDN博客&#xff0c;但是靜態版通訊錄的空間是無法被改變的&#xff0c;而且空間利用率也不高。為了解決靜態通訊錄這一缺點&#xff0c;這時就要有一個能夠隨著存入聯系人數量的增加而增大…

Ansys Zemax | 手機鏡頭設計 - 第 1 部分:光學設計

本文是 3 篇系列文章的一部分&#xff0c;該系列文章將討論智能手機鏡頭模組設計的挑戰&#xff0c;從概念、設計到制造和結構變形的分析。本文是三部分系列的第一部分&#xff0c;將專注于OpticStudio中鏡頭模組的設計、分析和可制造性評估。&#xff08;聯系我們獲取文章附件…

Vue緩存路由組件

目錄 一、使用 一、使用 作用&#xff1a;讓不展示的路由組件保持掛載&#xff0c;不被銷毀 <template><div><h2>Home組件內容</h2><div><ul class"nav nav-tabs"><li><router-link class"list-group-item"…

安防監控視頻云存儲平臺EasyNVR通道頻繁離線的原因排查與解決

安防視頻監控匯聚EasyNVR視頻集中存儲平臺&#xff0c;是基于RTSP/Onvif協議的安防視頻平臺&#xff0c;可支持將接入的視頻流進行全平臺、全終端分發&#xff0c;分發的視頻流包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等格式。為了滿足用戶的集成與二次開發需求&#xf…

OpenCV(二)——圖像基本處理(二)

目錄 2.圖像的幾何變換 2.1 圖像平移 2.2 圖像縮放 2.3 圖像旋轉 2.4 仿射變換 2.5 透視變換