AI 繪畫Stable Diffusion 研究(七) 一文讀懂 Stable Diffusion 工作原理


大家好,我是風雨無阻。


本文適合人群:

  • 想要了解AI繪圖基本原理的朋友。

  • 對Stable Diffusion AI繪圖感興趣的朋友。


本期內容:

  • Stable Diffusion 能做什么

  • 什么是擴散模型

  • 擴散模型實現原理

  • Stable Diffusion 潛擴散模型

  • Stable Diffusion文本如何影響圖片生成

  • Stable Diffusion Cross-attention 技術

  • Stable Diffusion noise schedule 技術

  • Stable Diffusion文生圖底層運行演示


一、 Stable Diffusion能做什么


通過前面幾篇文章關于 Stable Diffusion 整合包的安裝、ControlNet插件的介紹使、sd模型的安裝和使用以及文生圖功能的介紹后,相信看過的朋友應該都清楚的知道 Stable Diffusion 是做什么的吧?


對于新朋友,想詳細了解的話,請前往:

AI 繪畫Stable Diffusion 研究(一)sd整合包v4.2 版本安裝說明
AI 繪畫Stable Diffusion 研究(二)sd模型ControlNet1.1 介紹與安裝
AI 繪畫Stable Diffusion 研究(三)sd模型種類介紹及安裝使用詳解
AI 繪畫Stable Diffusion 研究(四)sd文生圖功能詳解(上)
AI 繪畫Stable Diffusion 研究(五)sd文生圖功能詳解(下)
AI 繪畫Stable Diffusion 研究(六)sd提示詞插件


這里再用最直白的話說一下:SD它是一個text-to-image模型 ,通過給定的 text prompt(文本提示詞),可生成一張匹配文本的圖片。


二、什么是擴散模型


大家都經常聽到有人說,Stable Diffusion是一種潛在擴散模型(Diffusion Models)。

那我們先弄明白什么是擴散模型?

為什么叫擴散模型呢?因為它的數學公式看起來非常像物理上的擴散現象。


1、前向擴散

假如我們訓練一個模型如下:

在這里插入圖片描述


正如上圖所示,是一個前向擴散的過程,它是在訓練圖像上逐漸添加噪聲,最后變成完全隨機噪聲圖,并最終無法辨認噪點圖對應的初始圖片。


這個過程就像是一滴墨水滴在一杯清水里,會慢慢擴散最終均勻分布在清水里一樣,且無法判斷它最初是從水杯的中心滴入,還是從邊緣滴入,擴散這個名字就是這么來的。


2、反向擴散


反向擴散的思想是:輸入一張噪點圖,反向擴散(Reverse Diffusion),讓上述過程獲得逆向從隨機噪聲圖生成清晰圖像的過程。


從反向擴散的角度來說,我們需要知道有多少“噪點”加入到了某張圖片里。


那么要知道答案的方式便是:訓練一個神經網絡來預測添加的噪點,這在SD里稱為噪點預測器(Noise Predicator),其本質是一個U-Net模型。


訓練流程為:

(1)、選擇一張訓練圖(例如一張貓的圖片)

(2)、生成隨機的噪點圖

(3)、給這張圖繼續增加多輪噪點

(4)、訓練Noise Predicator,預測加入了多少噪點,通過神經網絡訓練權重,并展示其正確答案。


在這里插入圖片描述


反向擴散訓練的重點下圖中的噪聲預測器(Noise Predicator),它可以通過訓練得出每次需要減掉的噪聲,每次需要減多少噪聲是預測出來的,從而實現還原清晰圖片的目的。


三、擴散模型實現原理


擴散模型(Diffusion Models)的成功,其實并非橫空出世,突然出現在人們的視野中。其實早在2015年就已有人提出了類似的想法,最終在2020年提出了擴散模型的生成技術。


以下是擴散模型推導公式:

在這里插入圖片描述


在這里插入圖片描述


在這里插入圖片描述


更詳細的原理:

參考:擴散模型詳解原理+代碼


通過前面的介紹,我們大概明白了,什么是擴散模型,但這并不是 Stable Diffusion的工作原理。

這是因為:上述擴散過程是在圖片空間里完成的,無論是模型訓練,還是生成圖片的過程,都是需要海量的算力支持和內存需求。


想象一下:一張512 x 512的圖片(包含3個顏色通道:紅、綠、藍),它的空間是786432維,也就是說我們要為一張圖片指定這么多的值。因此,基本無法在單個GPU上運行。


Stable Diffusion就是降低算力和內存需求的一個解決方案。它讓Stable Diffusion在消費級GPU上運行成為了可能。


**四、Stable Diffusion 潛擴散模型 **

Stable Diffusion 它是一個Latent Diffusion Model(潛擴散模型)。其方式是將圖片壓縮到一個“潛空間”(Latent Space)中,而不是在高維的圖片空間里工作。潛空間比圖片空間小了48倍,所以它可以節省大量計算,繼而運行速度更快。


擴散過程會分成很多步循環,而每一步的過程如下圖所示,將文本描述、隱變量、步數等數值傳入UNet,生成新的隱變量,而這個過程會涉及一些模型。

在這里插入圖片描述


在最后一步循環,將隱特征經由 Variational Autoencoder(VAE)解碼成圖像。

在這里插入圖片描述


這個過程的核心思想就是:壓縮圖像,它通過變分自編碼器 Variational Autoencoder(VAE)模型,把圖像壓縮到極致,我們把此類壓縮方式稱作降維,這種降維級別的壓縮不丟失重要信息。


經過壓縮后,圖像被稱作低維潛在(Latent)“圖像”,作為U-net的輸入,去潛空間(Latent Space)里一步一步降噪后,完成反向擴散的低維“圖片”還得通過VAE的解碼器,把圖像從潛空間轉換回像素空間(Pixel Space)。


VAE包含2部分:Encoder與Decoder。

  • Encoder將一張圖片壓縮到“潛空間”里的一個低維空間表示

  • Decoder從“潛空間”里的表示恢復為一張圖片

在這里插入圖片描述


下列代碼演示了VAE模型的使用方法,其中load_vae為根據配置init_config去初始化模型,然后從預訓練模型model.ckpt中讀取參數,預訓練模型的first_stage_model即指代VAE模型。


from ldm.models.autoencoder import AutoencoderKL
#VAE模型
def load_vae():#初始化模型init_config = {"embed_dim": 4,"monitor": "val/rec_loss","ddconfig":{"double_z": True,"z_channels": 4,"resolution": 256,"in_channels": 3,"out_ch": 3,"ch": 128,"ch_mult":[1,2,4,4],"num_res_blocks": 2,"attn_resolutions": [],"dropout": 0.0,},"lossconfig":{"target": "torch.nn.Identity"}}vae = AutoencoderKL(**init_config)#加載預訓練參數pl_sd = torch.load("model.ckpt", map_location="cpu")sd = pl_sd["state_dict"]model_dict = vae.state_dict()for k, v in model_dict.items():model_dict[k] = sd["first_stage_model."+k]vae.load_state_dict(model_dict, strict=False)vae.eval()return vae#測試vae模型
def test_vae():vae = load_vae()img = load_image("girl_and_horse.png")  #(1,3,512,512)   latent = vae.encode(img).sample()       #(1,4,64,64)samples = vae.decode(latent)            #(1,3,512,512)save_image(samples,"vae.png")test_vae()

五、Stable Diffusion 文本如何影響圖片生成


在 Stable Diffusion 模型中,prompt 是通過引導向量(guidance vector)來控制 U-Net 的。具體來說,prompt 會被編碼成一個文本嵌入向量(text embeddings),然后與其他輸入一起傳遞給 U-Net。

通過這種方式,prompt 能夠影響 U-Net 的輸出,從而在生成過程中引導模型產生符合預期的結果,即通過 prompt 產生我們想要的圖


在Stable Diffusion模型限制prompt在75個單詞。


下圖是文本提示詞(text prompt)如何處理并輸入到Noise Predictor的流程:


在這里插入圖片描述


根據上圖,我們可以看到這個流程:

首先,Tokenizer(分詞器)將每個輸入的單詞轉為一個數字,我們稱為token。

然后,每個token轉為一個768維的向量,稱為詞嵌入(embedding)。

最后,由Text Transformer處理詞嵌入,并可以被Noise predictor進行消費。


1、分詞器 (Tokenizer)

人類可以讀懂單詞,但計算機只能讀懂數字。所以這也是為什么文本提示詞首先要轉為單詞。

文本提示詞(text prompt)首先由一個CLIP tokenizer做分詞。

CLIP是一個深度學習模型,由Open AI開發,用于為任何圖片生成文本描述。


以下是CLIP具體的實例

展示了如何將文本“蘋果”通過CLIP技術轉化為能輸入到神經網絡中訓練的tokens數據。

這里使用Python和OpenAI庫來實現。


(1)、安裝依賴庫

pip install torch openai

(2)、導入相關庫

import torch import openai

(3)、加載CLIP模型

model, preprocess = openai.clip.load("ViT-B/32")

(4)、準備輸入文本

text_description = "蘋果"

(5)、將文本轉換為tokens

使用CLIP模型的tokenize方法將文本轉換為tokens

text_tokens = openai.clip.tokenize(text_description)

這里,text_tokens是一個PyTorch張量,形狀為(1, N),其中N是文本描述中的token數量。

在這個例子中,N=3,因為"蘋果"被分成了3個tokens。


(6)、 查看tokens

print(f"Tokens: {text_tokens}")

輸出結果可能類似于:

Tokens: tensor([[49406, 3782, 49407]])

這里,49406表示開始符號(start-of-sentence),3782表示“蘋果”,49407表示結束符號(end-of-sentence)。

通過以上步驟,我們將文本“蘋果”轉換為了tokens。


PS:

  • Stable Diffusion v1使用了CLIP模型的tokenizer

  • Tokenizer只能將其在訓練過程中見到過的單詞進行分詞

    例如:假設CLIP模型里有“dream”與“beach”單詞,但是沒有“dreambeach”單詞。

    Tokenizer會將“dreambeach”分成2個單詞“dream”與“beach”。

  • 1個單詞并非代表1個token,而是有可能進一步進行拆分

  • 空格也是token的一部分

    例如:短語 “dream beach” 產生了兩個token “dream” 和 “[space]beach”。

    這些標記與 “dreambeach” 產生的標記不同,后者是 “dream” 和 “beach”(beach 前沒有空格)。


2、詞嵌入(Embedding)


(1)、為什么需要詞嵌入(Embedding)?

因為有些單詞相互之間是非常相似,我們希望利用到這些語義信息。


例如:

man、gentleman、guy的詞嵌入是非常相近的,因此它們可以相互替換。

Monet、Manet以及Degas都以印象派的風格繪畫,但是方式各不相同。

這些名字看起來是非常相似,但是在詞嵌入(Embedding)里是不一樣的。


(2)、詞嵌入(Embedding) 是如何工作的?


Embedding 將輸入的tokens轉換為一個連續的向量來表示,這個向量可以捕捉文本中的語義信息。在我們的例子中,"蘋果"的tokens經過CLIP模型的encode_text方法后,會得到一個特征向量。


這個特征向量是一個高維空間中的點,通常具有固定的維度(在CLIP模型中,維度為512)。請注意,由于模型權重和隨機性的原因,每次運行時生成的特征向量可能略有不同。以下是一個示例輸出:


print(f"Text features: {text_features}")

輸出結果可能類似于:

Text features: tensor([[-0.0123,  0.0345, -0.0678, ...,  0.0219, -0.0456,  0.0789]])

這里,text_features是一個形狀為(1, 512)的PyTorch張量,其中包含了“蘋果”這個詞的向量表示。神經網絡可以利用這個向量表示進行訓練和預測任務。


Stable diffusion v1使用Open AI的ViT-L/14模型,詞嵌入為768維的向量。


3、文本轉換器(text transformer)


(1)、為什么需要text transformer


既然通過embedding后可以直接輸入到模型中進行訓練,為何在stable diffusion中還需要將embedding通過text transformer轉換后再作為模型的輸入呢?


這是因為Stable Diffusion模型是一個圖像生成模型,它需要理解輸入文本的語義信息以生成與之相關的圖像。直接使用基本的文本embedding可能無法充分捕捉到文本中的復雜語義關系。通過使用text transformer,可以獲得一個更豐富、更具表現力的文本表示,這有助于提高生成圖像的質量和與輸入文本的相關性。


使用text transformer 在捕捉文本語義信息時,能夠考慮到更多上下文關系和抽象概念

這個轉換器就像是一個通用的條件(conditioning)適配器。


(2)、text transformer轉換示例


下面以"蘋果"為例進行說明。

假設我們已經獲得了"蘋果"的基本embedding(一個形狀為(1, 512)的PyTorch張量):

text_features = tensor([[-0.0123,  0.0345, -0.0678, ...,  0.0219, -0.0456,  0.0789]])

接下來,我們將這個張量輸入到text transformer中:

transformed_text_features = text_transformer(text_features)

經過text transformer處理后,我們可能會得到一個新的張量,如:

print(f"Transformed text features: {transformed_text_features}")

輸出結果可能類似于:

Transformed text features: tensor([[ 0.0234, -0.0567,  0.0890, ..., -0.0321,  0.0672, -0.0813]])

這個新的張量(形狀仍為(1, 512))包含了更豐富的語義信息,例如上下文關系和抽象概念。

這有助于Stable Diffusion模型更好地理解輸入文本,并生成與之相關的圖像。


請注意:

由于模型權重和隨機性的原因,每次運行時生成的特征向量可能略有不同。

此外,具體的變化過程取決于所使用的text transformer結構和參數。


六、Stable Diffusion Cross-attention技術


Cross-attention 是通過提示詞產生圖片的核心技術。

文本轉換器的輸出,會被noise predictor在U-Net中使用到多次。

U-Net以一個叫做cross-attention機制的方式來使用它,cross-attention機制允許模型在不同的特征層次上關注相關的區域,從而提高生成結果的質量,這即是prompt適配圖片的地方。


下面代碼是stable diffusion所使用的transformers塊,實現了cross-attention:

class SpatialTransformer(nn.Module):"""Transformer block for image-like data.First, project the input (aka embedding)and reshape to b, t, d.Then apply standard transformer action.Finally, reshape to image"""def __init__(self, in_channels, n_heads, d_head,depth=1, dropout=0., context_dim=None):super().__init__()self.in_channels = in_channelsinner_dim = n_heads * d_headself.norm = Normalize(in_channels)self.proj_in = nn.Conv2d(in_channels,inner_dim,kernel_size=1,stride=1,padding=0)self.transformer_blocks = nn.ModuleList([BasicTransformerBlock(inner_dim, n_heads, d_head, dropout=dropout, context_dim=context_dim)for d in range(depth)])self.proj_out = zero_module(nn.Conv2d(inner_dim,in_channels,kernel_size=1,stride=1,padding=0))def forward(self, x, context=None):# note: if no context is given, cross-attention defaults to self-attentionb, c, h, w = x.shapex_in = xx = self.norm(x)x = self.proj_in(x)x = rearrange(x, 'b c h w -> b (h w) c')for block in self.transformer_blocks:x = block(x, context=context)x = rearrange(x, 'b (h w) c -> b c h w', h=h, w=w)x = self.proj_out(x)return x + x_in

七、Stable Diffusion noise schedule 技術


1、什么是 noise schedule ?

噪聲通過多次U-Net的處理,最終會輸出我們想要的圖片。

在這多次處理中,每一次的降噪的幅度是不同的,所以我們就要通過schedulers來控制每次降噪的幅度(幅度一般是遞減的)。這個技術就叫做 noise schedule

如圖:


在這里插入圖片描述


那么為什么要使用 noise schedule 技術呢?


在 Stable Diffusion 這種生成模型中,U-Net 是一個核心組件,用于從噪聲圖像中逐步恢復出原始圖像。在多次迭代過程中,降噪幅度逐漸減小的原因是為了更精細地恢復圖像的細節和結構。


Stable Diffusion 的過程可以看作是一個逆向擴散過程,它從一個高度噪聲的圖像開始,然后通過多個步驟逐漸去除噪聲以重建原始圖像。在這個過程中,U-Net 被用來預測每一步的降噪操作。


在前幾輪迭代中,圖像中的噪聲較大,因此需要較大的降噪幅度來消除這些噪聲。隨著迭代次數的增加,圖像中的噪聲逐漸減小,因此降噪幅度也應相應減小。這樣做的目的是避免過度平滑或損壞已經恢復的圖像細節。


通過逐漸減小降噪幅度,U-Net 可以更好地控制去噪過程,使其在保留圖像細節的同時有效地去除噪聲。這有助于生成更清晰、更真實的圖像。


這里舉一個文生圖的代碼,用于說明noise schedule技術:

def txt2img():#unetunet = load_unet()#調度器scheduler = lms_scheduler()scheduler.set_timesteps(100)#文本編碼prompts = ["a photograph of an astronaut riding a horse"]text_embeddings = prompts_embedding(prompts)text_embeddings = text_embeddings.cuda()     #(1, 77, 768)uncond_prompts = [""]uncond_embeddings = prompts_embedding(uncond_prompts)uncond_embeddings = uncond_embeddings.cuda() #(1, 77, 768)#初始隱變量latents = torch.randn( (1, 4, 64, 64))  #(1, 4, 64, 64)latents = latents * scheduler.sigmas[0]    #sigmas[0]=157.40723latents = latents.cuda()#循環步驟for i, t in enumerate(scheduler.timesteps):  #timesteps=[999.  988.90909091 978.81818182 ...100個latent_model_input = latents  #(1, 4, 64, 64)  sigma = scheduler.sigmas[i]latent_model_input = latent_model_input / ((sigma**2 + 1) ** 0.5)timestamp = torch.tensor([t]).cuda()with torch.no_grad():  noise_pred_text = unet(latent_model_input, timestamp, text_embeddings)noise_pred_uncond = unet(latent_model_input, timestamp, uncond_embeddings)guidance_scale = 7.5 noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)latents = scheduler.step(noise_pred, i, latents)vae = load_vae()latents = 1 / 0.18215 * latentsimage = vae.decode(latents.cpu())  #(1, 3, 512, 512)save_image(image,"txt2img.png")txt2img()

八、Stable Diffusion 文生圖底層運行演示


在文本生成圖的場景下,我們給SD模型輸入一組文本提示詞,它可以返回一張圖片。


第一步、 Stable Diffusion在潛空間里生成一個隨機張量。

我們通過設置隨機種子seed來控制這個張量的生成。如果我們設置這個隨機種子為一個特定的值,則會得到相同的隨機張量。這就是我們在潛空間里的圖片。但是當前還全是噪點。

在這里插入圖片描述


第二步、 Noise predictor U-Net將潛噪點圖已經文本提示詞作為輸入,并預測噪點

此噪點同樣也在潛空間內(一個4 x 64 x 64的張量)

在這里插入圖片描述


第三步、從潛圖片中抽取潛噪點,并生成了新的潛圖片

在這里插入圖片描述


第二步 與 第三步重復特定采樣次數,例如20次。


第四步、VAE 的decoder將潛圖片轉回像素空間

這便是我們通過SD模型最終得到的圖片。

在這里插入圖片描述


參考資料:

1. How does Stable Diffusion work?

2. stable-diffusion

3.擴散模型詳解原理+代碼

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

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

相關文章

【量化課程】02_4.數理統計的基本概念

2.4_數理統計的基本概念 數理統計思維導圖 更多詳細內容見notebook 1.基本概念 總體:研究對象的全體,它是一個隨機變量,用 X X X表示。 個體:組成總體的每個基本元素。 簡單隨機樣本:來自總體 X X X的 n n n個相互…

資料分析(二)—— 速算技巧 - 高照

常用方法 A * 1.5 A A的一半 120*1.5 120 60 A * 1.1 A 錯位相加 123*1.1 12312.3 A * 0.9 A 錯位相減 123*0.9 123-12.3 A/5 A * 2 ,小數點左移一位 24/5 4.8 A/25 A * 4 ,小數點左移兩位 24/25 0.96 A/125 A * 8 ,小數點左移…

mtl文件解釋

.mtl文件是一種文本文件,通常用于與三維模型文件(如.obj文件)一起描述三維模型的材質(Material)屬性和外觀。這些屬性包括顏色、紋理、光照等信息,以便在渲染或展示三維模型時能夠正確地呈現出模型的外觀效…

【leetcode】【圖解】617. 合并二叉樹

題目 難度:簡單 給你兩棵二叉樹: root1 和 root2 。 想象一下,當你將其中一棵覆蓋到另一棵之上時,兩棵樹上的一些節點將會重疊(而另一些不會)。你需要將這兩棵樹合并成一棵新二叉樹。合并的規則是&#xf…

Python web實戰之Django的AJAX支持詳解

關鍵詞:Web開發、Django、AJAX、前端交互、動態網頁 今天和大家分享Django的AJAX支持。AJAX可實現在網頁上動態加載內容、無刷新更新數據的需求。 1. AJAX簡介 AJAX(Asynchronous JavaScript and XML)是一種在網頁上實現異步通信的技術。通過…

electron 使用node C++插件 node-gyp

node C插件使用,在我們常規使用中,需要使用node-gyp指定對飲的node版本即可 在electron的使用中,我們需要指定的是electron版本要不然會報錯使用的v8內核版本不一致導致C擴展無法正常引入 electron官方文檔-node原生模塊 package.json {&quo…

標準的rust后端項目的結構是怎樣的呢?

一個標準的Rust后端項目通常遵循一種常見的項目結構,以下是一個示例: . ├── Cargo.toml ├── src │ ├── main.rs │ ├── lib.rs │ ├── handlers │ │ ├── mod.rs │ │ └── user_handler.rs │ ├── models │…

一百五十四、Kettle——Linux上安裝Kettle9.3(踩坑,親測有效,附截圖)

一、目的 由于kettle8.2在Linux上安裝后,共享資源庫創建遇到一系列問題,所以就換成kettle9.3 二、kettle版本以及安裝包網盤鏈接 kettle9.3.0安裝包網盤鏈接 鏈接:https://pan.baidu.com/s/1MS8QBhv9ukpqlVQKEMMHQA?pwddqm0 提取碼&…

解決電腦聲音正常但就是某些游戲沒聲音問題

電腦聲音正常,玩普遍游戲也正常,就有游戲不出聲音 詳細介紹經過,不喜歡的請直接跳 第三部分。 一、先說下起因現象。 1 大富翁11 沒聲音。 前段時間無聊懷舊就買了個大富翁11玩玩,近二十年前的老臺式機正常無問題。后來想在性能…

Java多線程編程:實現并發處理的高效利器

Java多線程編程:實現并發處理的高效利器 作者:Stevedash 發表于:2023年8月13日 20點45分 來源:Java 多線程編程 | 菜鳥教程 (runoob.com) ? 在計算機領域,多線程編程是一項重要的技術,可以使程序同時執…

InnoDB文件物理結構解析6 - FIL_PAGE_INDEX

本文討論Secondary Key Page的解析,也就是表非主鍵索引的記錄存儲。與Clustered Key Page有相同的基本記錄結構,也細分為Leaf Page和Non-Leaf Page,我們先看結構: ### Contents (Secondary Key - Leaf Page) ### ---------------…

從小白到大神之路之學習運維第79天-------Kubernetes網絡組件詳解

第四階段 時 間:2023年8月14日 參加人:全班人員 內 容: Kubernetes網絡組件詳解 目錄 一、Kubernetes網絡組件 (一)Flannel網絡組件 (二)Calico 網絡插件 (1)…

設計模式——建造者(Builder)模式

建造者模式(Builder Pattern),又叫生成器模式,是一種對象構建模式 它可以將復雜對象的建造過程抽象出來,使這個抽象過程的不同實現方法可以構造出不同表現的對象。建造者模式是一步一步創建一個復雜的對象,…

(14)嵌套列表,Xpath路徑表達式,XML增刪查改,Implicit,Operator,Xml序列化,淺拷貝與深拷貝

一、作業問題 1、問:listbox1.items[i]返回的object是指的字符串嗎? 答:items是真正的對象集合,在Add時加的是Person對象p,則里面的item就是Person對象p。 但是,在listbox1顯…

在單元測試中使用Jest模擬VS Code extension API

對VS Code extension進行單元測試時通常會遇到一個問題,代碼中所使用的VS Code編輯器的功能都依賴于vscode庫,但是我們在單元測試中并沒有添加對vscode庫的依賴,所以導致運行單元測試時出錯。由于vscode庫是作為第三方依賴被引入到我們的VS C…

[oneAPI] BERT

[oneAPI] BERT BERT訓練過程Masked Language Model(MLM)Next Sentence Prediction(NSP)微調 總結基于oneAPI代碼 比賽:https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel DevCloud for oneAPI&…

JVM 中的編譯器

在Java的世界里,JVM(Java Virtual Machine)扮演了重要的角色。JVM是一個虛擬機,是Java程序的運行環境,它能夠將Java字節碼文件解釋執行,使得Java程序可以跨平臺。在JVM內部,有一個重要的組件就是編譯器,它的作用就是將Java源代碼編譯成字節碼,讓JVM可以識別并執行。 …

redis集群和分片-Redis Cluster:分布式環境中的數據分片、主從復制和 Sentinel 哨兵

當涉及到 Redis 中的集群、分片、主從復制和 Sentinel 哨兵時,這些是構建分布式 Redis 環境中非常重要的概念和組件。下面詳細介紹這些概念以及它們在分布式環境中的作用。 Redis Cluster Redis Cluster 是 Redis 官方提供的分布式解決方案,用于管理和…

React源碼解析18(4)------ completeWork的工作流程【mount】

摘要 經過上一章,我們得到的FilberNode已經具有了child和return屬性。一顆Filber樹的結構已經展現出來了。 那我們最終是想在頁面渲染真實的DOM。所以我們現在要在completeWork里,構建出一顆離屏的DOM樹。 之前在說FilberNode的屬性時,我們…

zabbix案例--zabbix監控Tomcat

目錄 一、 部署tomcat 二、配置zabbix-java-gateway 三、配置zabbix-server 四、配置zabbix-web界面 一、 部署tomcat tar xf apache-tomcat-8.5.16.tar.gz -C /usr/local/ ln -sv /usr/local/apache-tomcat-8.5.16/ /usr/local/tomcat cd /usr/local/tomcat/bin開啟JMX…