20251022筆記 內容可能有錯誤,請參考原始影片 [李宏毅【機器學習 2023】(生成式 AI)](https://www.youtube.com/playlist?list=PLJV_el3uVTsOePyfmkfivYZ7Rqr2nMk3W) 今日影片 [【生成式AI】速覽圖像生成常見模型](https://youtu.be/z83Edfvgd9g?si=Sx39mxCm_eilArr_) [【生成式AI】淺談圖像生成模型 Diffusion Model 原理](https://youtu.be/azBugJzmz-o?si=Y4dQREpyYh54R9iJ) [【生成式AI】Stable Diffusion、DALL-E、Imagen 背後共同的套路](https://youtu.be/JbfcAaBT66U?si=GUexs0TITX8hB7hV) ### 【生成式AI】速覽圖像生成常見模型 大綱 **I. 圖像生成的特性與挑戰** A. 圖像資訊量龐大,勝過千言萬語。 B. 機器需進行大量「腦補」以彌補文字輸入的不足。 C. 圖像生成輸出具有高度變化的可能性。 **II. 從自動迴歸到非自動迴歸方法** A. 文本生成的自動迴歸方法 (如 GPT)。 B. 圖像生成的自動迴歸應用 (像素生成)。 C. 非自動迴歸方法的挑戰與需求。 **III. 現代圖像生成模型的通用套路** A. 圖像生成的正確答案是一個分佈 (Distribution)。 B. 引入額外的輸入:潛在向量 (Latent Vector $z$)。 C. 模型的任務:將簡單分佈扭曲成複雜的圖像分佈 $p(x|y)$。 **IV. 常見圖像生成模型速覽** A. 變分自動編碼器 (VAE)。 B. 流式模型 (Flow-based Model)。 C. 擴散模型 (Diffusion Model)。 D. 生成對抗網絡 (GAN)。 --- ### I. 圖像生成的特性與挑戰 圖像生成任務,例如透過文字描述(像是「正在奔跑的狗」)生成一張圖,與生成文字相比有其特殊性。 * **資訊量巨大:** 俗話說「一張圖勝過千言萬語」。如果想要將一張圖描述成文字,其資訊量遠遠超過僅僅描述一張圖片的文字輸入。 * **需要腦補:** 許多細節資訊,例如狗奔跑的位置(如在街道上)、背景(草原、沙地或市區),並不在人類輸入的文字描述中。因此,機器需要進行**大量的腦補**才能生成出好的圖像。 * **輸出多樣性:** 對於相同的輸入文字,圖像生成的輸出具有**非常多不同的樣貌**或可能性。這與文字生成任務(如翻譯)中輸出的可能性較為有限的情況不同。 ### II. 從自動迴歸到非自動迴歸方法 #### A. 自動迴歸方法 (Autoregressive Approach) 文字生成通常採用自動迴歸(autoregressive)的方法。 1. **流程:** 模型輸入一個句子,然後輸出一個機率分佈。根據這個機率分佈進行採樣 (sample) 取出一個文字,再根據取出的文字產生新的機率分佈,持續產生結果。 2. **圖像應用:** 視覺上,圖像生成似乎也可以套用幾乎一模一樣的做法。 * 模型可以輸入文字。 * 輸出的分佈不是文字的分佈,而是**顏色的分佈**(通常以像素 pixel 為單位)。 * 一個像素由 RGB 三個顏色組成。理論上,有 $256 \times 256 \times 256$ 種顏色組合,但在實際生成中,可以選擇較少的顏色(例如 256 色就夠了)。 3. **GPT 的圖像版本:** OpenAI 曾有一個圖像版的 GPT。它將二維的圖片(像素值)變成一排(一個序列),將其視為類似語言模型的問題。這種一排一排生成像素的方法被稱為 **raster sequence**。 #### B. 非自動迴歸方法的挑戰 雖然自動迴歸方法可以生成高解析度的圖像,但它**太耗費時間**。因此,當今高效的圖像生成模型多數採用**非自動迴歸方法**(Non-autoregressive method),概念上是同時生成所有位置的顏色分佈。 * **挑戰:** 如果採用非自動迴歸方法,讓每個像素獨立各自生成,會得到非常糟的結果。 * **原因:** 因為正確答案是一個分佈,而非單一標準答案。如果每個像素都分開採樣,有些像素可能想畫往左跑的狗,有些想畫往右跑的狗,所有像素拼湊起來就會不連貫。 ### III. 現代圖像生成模型的通用套路 由於圖像生成的問題中,正確答案 $x$ 是一個分佈 $p(x|y)$(給定文字 $y$ 後的圖像分佈),這個分佈非常複雜。 #### A. 引入額外的潛在輸入 為了處理這種複雜的多樣性,現今所有的圖像生成模型都有一個**共同的套路**:它們都需要一個**額外的輸入**。 1. **來源:** 這個額外輸入 $z$ 是一個向量,通常是從一個**簡單的機率分佈**中採樣出來的,例如 Normal distribution(常態分佈)或 Uniform distribution。 2. **特性:** 這個潛在向量 $z$ 必須被視為一個**高維**的向量,丟給生成模型後,才能夠產生圖像。 3. **模型任務:** 圖像生成模型的任務就是**產生這個對應的關係**。它必須想辦法將 Normal distribution 裡面採樣出來的東西 $z$,對應到正確的圖像分佈 $p(x|y)$ 中的每一個可能結果。 ### IV. 常見圖像生成模型速覽 #### A. 變分自動編碼器 (VAE, Variational Autoencoder) VAE 目的在訓練一個解碼器 (Decoder) $D$,使其能夠以潛在向量 $z$ 作為輸入,輸出正確的圖像 $x$。 1. **訓練機制:** 由於我們不知道 $z$ 與圖像 $x$ 的對應關係,因此需要訓練一個**編碼器 (Encoder) $E$**,將圖像 $x$ 壓縮成向量 $z$。 2. **串聯訓練:** 將編碼器 $E$ 和解碼器 $D$ 串聯起來,輸入一張圖 $x$,變成向量 $z$,再透過 $D$ 還原回原圖 $x'$。訓練目標是讓輸入 $x$ 和輸出 $x'$ 越接近越好。 3. **核心限制:** 僅靠上述訓練不夠。VAE 必須加入一個額外的限制,**強迫中間的向量 $z$ 是 Normal distribution**(常態分佈)。 #### B. 流式模型 (Flow-based Model) Flow-based Model的概念是試圖訓練一個編碼器 $E$。 1. **目標:** 讓編碼器 $E$ 輸入一張圖 $x$,輸出的向量 $z$ 的分佈是 Normal distribution。 2. **可逆性 (Invertibility):** Flow-based Model的關鍵是**強迫這個編碼器 $E$ 是一個可逆 (invertible) 的函數**。如果 $E$ 是可逆的,那麼其逆函數 $E^{-1}$ 就可以直接當作解碼器 (Decoder) 來使用。 3. **架構限制:** 為了保證 $E$ 是可逆的,網路架構必須受到刻意限制,不是隨意的網路架構都可以充當可逆編碼器。 4. **維度要求:** 因為 $E$ 必須是可逆的,輸出的向量 $z$ 的維度**必須與輸入的圖形 $x$ 維度一樣大**。例如,輸入是 $256 \times 256$ 的圖片,輸出的向量也必須要有 $256 \times 256$ 個數字。 #### C. 擴散模型 (Diffusion Model) 擴散模型是作業六的重點。 1. **順向過程 (Forward Process/Diffusion):** 將一張圖片**一直加雜訊**(noise),直到最後圖片完全看不出來是什麼,看起來像純粹的噪點。 2. **逆向過程 (Reverse Process/Generation):** 透過訓練一個 **denoising model**(去噪模型)。生成圖片的方法就是從一個純雜訊的輸入開始,讓去噪模型慢慢地將雜訊去掉,從而產生出圖像。 #### D. 生成對抗網絡 (GAN, Generative Adversarial Network) GAN 只訓練一個生成器(在 VAE 架構中稱為 Decoder),但沒有訓練編碼器 (Encoder)。 1. **判別器 (Discriminator):** GAN 額外訓練一個判別器 $D$,其工作是用來**分辨**輸入的圖片是生成器產生的**假圖** ($p_g(x)$) 還是**真實的圖片** ($p_{data}(x)$)。 2. **對抗訓練:** 生成器 $G$ 必須調整其參數,盡量讓判別器 $D$ 表現越差越好。如果判別器無法分辨真假圖片,就代表生成器產生的分佈 $p_g(x)$ 與真實圖片的分佈 $p_{data}(x)$ 非常接近。 3. **整合性:** GAN 是一種訓練模式。它可以作為一個「外掛」,加到 VAE、Flow model 或 Diffusion model 等新興的生成模型上。 ### V. 模型間的關係與整合 * **模型功能差異:** VAE、Flow model 和 Diffusion model 都在解決將 $z$ 映射到 $x$(解碼)的問題,但採取的模式不同。Flow model 是透過架構限制保證可逆性。Diffusion model 則是透過迭代去噪來實現生成(解碼)。 * **GAN 的正交性:** GAN 可以看作是 VAE 和 Flow model 的另一個角度。你可以總是可以將一個成功的 VAE 或 Flow model 後面再接上一個 Discriminator。 ### 【生成式AI】淺談圖像生成模型 Diffusion Model 原理 大綱 **I. 擴散模型(Diffusion Model)的概述與運作原理** A. 擴散模型在頂尖圖像生成系統中的應用。 B. 圖像生成的逆向過程:從純雜訊到清晰圖像。 **II. 去噪模型(Denoising Model)的機制** A. 統一的去噪模型與 Step ID 的輸入。 B. 噪聲預測器(Noise Predictor)的核心作用。 **III. 噪聲預測器的訓練** A. 訓練數據的生成:順向過程(Forward Process / Diffusion)。 B. 訓練配對:輸入、Step ID 與目標輸出(Ground Truth Noise)。 **IV. 納入文字條件與數據集需求** A. 條件式生成:將文字敘述加入去噪模組。 B. 訓練資料的規模:LAION-5B 等大型數據集。 --- ### I. 擴散模型(Diffusion Model)的概述與運作原理 #### A. 擴散模型的應用 目前在文字生成圖像領域中較為成功的系統,如 **DALL-E**、**Imagen** 或 **Stable Diffusion**,基本上都採用擴散模型(Diffusion Model)的方法來進行圖像生成。 #### B. 圖像生成的逆向過程 (Reverse Process) 擴散模型的運作方法是透過一個**逆向過程**(Reverse Process)來生成圖像。 1. **起始點:** 生成圖像的底部是從採樣一個**完全都是雜訊**的圖(或向量 $z$)開始。 2. **向量維度:** 這個採樣出來的向量的維度必須與要生成的圖片大小**一模一樣**。例如,如果目標是 256 x 256 的圖片,則向量維度也要是 256 x 256。 3. **去噪迭代:** 接下來使用一個去噪模組(Denoising Module)進行迭代處理。 * 輸入一張全是雜訊的圖,模型會輸出並去掉一點雜訊,圖像可能會開始看到一些形狀。 * 隨著去噪操作不斷重複,圖像會逐漸變得清晰,最終看到生成的形狀。 4. **時間步(Step ID):** 去噪的次數或步驟是隨著**時間**推進的。 * 從完全是雜訊的輸入開始,編號(ID)較大(例如從 999 開始)。 * 生成最終清晰圖像的步驟,編號較小(例如到 0 或 1)。 5. **概念比喻:** 這個過程可以比喻為雕刻家移除了大理石中不必要的部分,因為圖像的形狀其實**本來就已經在雜訊之中**。 ### II. 去噪模型(Denoising Model)的機制 #### A. 統一模型與動態輸入 在實際應用中,圖像生成系統常會反覆使用**同一個**去噪模型。 * 由於在不同階段(例如從 Step 999 到 Step 1),輸入圖像的noise程度差異非常大,單純使用同一個模型可能無法做得很好。 * 因此,這個去噪模型會多吃一個額外的輸入,即代表**noise嚴重程度**的資訊,也就是當前在第幾個 Step 的編號 ID ($t$)。 * 模型會根據這個 Step ID 的資訊,做出不同的回應。 #### B. 噪聲預測器 (Noise Predictor) 的核心作用 去噪模型模組內部實際做的事情,是訓練一個 **Noise Predictor**(噪聲預測器)。 1. **Noise Predictor 的輸入:** 它接收兩個主要輸入: * 要被去噪的圖像 ($x_t$)。 * 當前進行到的步驟代號(Step ID, $t$),即noise的嚴重程度。 2. **Noise Predictor 的輸出:** 它輸出的是**一張雜訊**,預測在這張輸入圖像中,雜訊應該長什麼樣子。 3. **去噪達成:** 最終的去噪效果是透過將 **Noise Predictor 輸出的雜訊**,從**輸入的待去噪圖像**中減去,從而產生去噪結果。 * *選擇原因:* 論文中多數選擇訓練一個 Noise Predictor,因為**產生一張圖中包含的雜訊**,可能比訓練一個模型直接輸出帶有複雜結構(例如一隻貓)的圖像要簡單。 ### III. 噪聲預測器的訓練 #### A. 訓練數據的生成:順向過程 (Forward Process) 訓練 Noise Predictor 需要**成對的資料**(paired data),即模型需要被告知在特定圖像中,雜訊的**真實樣貌**(Ground Truth Noise)。這些訓練資料是**人為創造**出來的。 1. **數據創造方法:** 從真實的、乾淨的圖像開始。 2. **擴散過程(Diffusion):** 從高斯分佈(Gaussian Distribution)中採樣noise,並不斷地將noise加到圖像上。 3. **終點:** 這個**加噪音的過程**(稱為 **Forward Process** 或 **Diffusion**)持續進行,直到最後圖像完全看不出是什麼東西。 4. **結果:** 完成這個順向過程後,我們就得到了 Noise Predictor 的訓練資料。 #### B. 訓練配對 訓練配對如下: * **網路輸入:** 加完雜訊的圖像 ($x_t$),以及當前是第幾個 Step 的 ID ($t$)。 * **目標輸出(Ground Truth):** 當初被加入的**雜訊** ($\epsilon$)。 * **訓練目標:** 訓練網路使其輸出的noise,與當初加入的真實noise越接近越好。 ### IV. 納入文字條件與數據集需求 #### A. 條件式生成 (Conditional Generation) 如果目標是訓練一個**吃文字產生圖片**的圖像生成模型,在訓練時仍然需要成對的圖像與文字資料。 * **方法:** 將文字敘述作為一個**額外輸入**,加入到去噪模組中。 * **Noise Predictor 的輸入變更:** 訓練時,Noise Predictor 現在除了吃加雜訊後的圖像和 Step ID,還會多吃一個**文字**的輸入。 * **作用:** 模型會根據這三個輸入(圖、ID、文字),產生應被消掉的noise,從而引導生成符合文字敘述的圖像。 #### B. 訓練資料的規模與來源 強大的圖像生成模型需要極大量的成對訓練資料。 * **數據集規模:** 相較於作業中使用的 7 萬張帶有類別標記的圖像,頂尖的模型(如 DALL-E 2、Imagen)使用的圖像數量要龐大得多。 * **LAION 數據集:** 許多目前強大的圖像生成模型(如 Stable Diffusion)的訓練數據來源於 **LAION**。LAION 數據集包含了 **58.5 億**(5.85 Billion)張圖。 * **數據內容:** LAION 不僅包含英文圖文對,還包含中文和日文的對應,這解釋了為什麼這些模型能夠理解並根據不同的語言(如中文)產生圖像。 ### 【生成式AI】Stable Diffusion、DALL-E、Imagen 背後共同的套路 大綱 **I. 頂尖圖像生成模型的通用架構** A. 模型組成:三個核心元件(Text Encoder, Generation Model, Decoder)。 B. 頂尖系統的應用範例:Stable Diffusion, DALL-E, Imagen。 **II. 核心元件一:文字編碼器 (Text Encoder)** A. 功用:將文字敘述轉換為向量。 B. 重要性:對最終生成結果品質有決定性影響。 C. 評估指標:FID(越小越好)與 CLIP Score(越大越好)。 **III. 核心元件三:圖像解碼器 (Decoder) 與潛在表徵 (Latent Representation)** A. 功能:將中間產物(壓縮版)還原為原始圖像。 B. 訓練方式:通常透過 Autoencoder 分開訓練,無需文字數據。 C. 中間產物特性:潛在表徵 (Latent Representation),維度小於原始圖像。 **IV. 核心元件二:生成模型 (Generation Model) - 潛在擴散** A. 任務:根據文字表徵生成潛在表徵。 B. 運作機制:將擴散過程應用於**潛在空間**而非像素空間。 C. 生成流程:從純雜訊的潛在向量開始,透過迭代去噪達成。 --- ### I. 頂尖圖像生成模型的通用架構 #### A. 結構與組成元件 目前表現優異的圖像生成模型,例如 **Stable Diffusion**,其背後的套路和內部結構大致相同。這些模型基本包含三個核心元件: 1. **Text Encoder(文字編碼器):** 負責處理輸入的文字敘述,將其轉換為向量表示。 2. **Generation Model(生成模型):** 今天多數採用 **Diffusion Model**(擴散模型),它接收輸入的雜訊(粉紅色的向量)和文字的向量,產生一個**中間產物**。 3. **Decoder(解碼器):** 負責將這個中間產物(即圖像的壓縮版)還原為**原始的、完整的高解析度圖像**。 通常這三個模型是**分開訓練**,然後再將它們串接起來使用。 #### B. 通用套路案例 許多領先的文字生成圖像模型都採用類似的流程: * **Stable Diffusion:** 採用 Text Encoder 處理文字,Diffusion Model 產生壓縮版的中間產物,再用 Decoder 還原。 * **DALL-E 系列:** 也需要 Text Encoder,然後使用一個生成模型(如 Auto Regressive Model 或 Diffusion Model)來生成圖片的**壓縮版本**,最後用 Decoder 還原。 * **Imagen (Google):** 也是先有 Text Encoder,接著用生成模型生成圖片的壓縮版本,不過 Imagen 產生的中間產物是人眼看得懂的較小圖,接著使用 Decoder(在 Imagen 論文中稱為 Decoder Model)將小圖生成大圖。 ### II. 核心元件一:文字編碼器 (Text Encoder) #### A. 功能與重要性 Text Encoder 的作用是將輸入的文字進行理解並編碼成向量。 * **影響力:** 研究顯示,Text Encoder 的品質對最終圖像的生成結果影響**非常大**。例如,Google Imagen 的實驗結果表明,隨著使用的 Text Encoder 模型的規模越來越大,生成的圖像品質也越來越高。 * **原因:** 一個好的 Text Encoder 可以幫助生成模型處理那些它在圖像與文字配對資料中**沒有見過**的奇特文字或敘述,因此對結果的影響非常重要。 #### B. 圖像生成模型的評估指標 由於圖像生成任務沒有單一的標準答案,需要特定的方法來評估模型的好壞。 1. **FID (Fréchet Inception Distance):** * **方法:** FID 需要一個預訓練好的 **CNN Model**(圖像分類模型,例如 Inception Model)。將真實圖像和機器生成的圖像都丟入這個 CNN 中,提取出它們的 **Latent Representation**。 * **計算:** 假設這兩組 Representation 都遵循高斯分佈 (Gaussian Distribution),然後計算這兩個高斯分佈之間的 **距離**(稱為 Fréchet Distance)。 * **判斷標準:** 兩組 Representation 越接近,FID 值就越小,代表生成效果越好。通常需要採樣大量的圖像(如 10K 張)來量測 FID。 2. **CLIP Score (Contrastive Language-Image Pre-training Score):** * **背景:** CLIP 是一種模型,使用 4 億組圖像與文本數據訓練出來的。它包含一個 Image Encoder 和一個 Text Encoder。 * **方法:** 將機器生成的圖片丟入 Image Encoder 得到圖像向量,將當初生成這張圖片的文字敘述丟入 Text Encoder 得到文字向量。 * **計算:** 算這兩個向量的相似度(例如餘弦相似度 cosine similarity),如果這兩個向量的相似度高,則代表生成的圖片與文字描述有良好的對應關係。 * **判斷標準:** CLIP Score 越大越好。 ### III. 核心元件三:圖像解碼器 (Decoder) 與潛在表徵 #### A. 解碼器的功能與訓練 Decoder 的作用是將生成模型產生的中間產物或潛在表徵(Latent Representation)還原成原始的圖像。 * **訓練優勢:** Decoder 的訓練**不需要文字資料**。它只需要大量圖像資料就能訓練。 * **訓練機制(Autoencoder):** 如果中間產物是某種 Latent Representation,則訓練方式通常是透過 **Autoencoder**。 1. 訓練一個 Encoder 將原始圖像壓縮成 Latent Representation。 2. 訓練一個 Decoder 將 Latent Representation 還原成原始圖像。 3. 訓練目標是讓輸入圖像和還原後的圖像越接近越好。 4. 訓練完成後,只需取出這個 Decoder 供生成流程使用。 #### B. 中間產物:潛在表徵 (Latent Representation) * **形式:** 潛在表徵通常可以寫成一個維度較小的矩陣 $\text{小} H \times \text{小} W \times \text{小} C$。 * $\text{小} H$ 和 $\text{小} W$ 是原始圖像 $H$ 和 $W$ 的縮小結果(例如 $1/10$)。 * $\text{小} C$ 是 Channel 的數量,表示在潛在小圖上,每個位置是用多少個數字來表示(如果 $\text{小} C=3$ 就是 RGB 三個 Channel)。 * **用途:** Stable Diffusion 和 DALL-E 傾向使用這種 Latent Representation 作為中間產物,而 Imagen 則使用人眼看得懂的小圖。 ### IV. 核心元件二:生成模型 (Generation Model) #### A. 潛在空間擴散 (Latent Diffusion) 生成模型(在 Latent Diffusion 體系中)的作用是接收文字的 Representation,並在潛在空間中生成壓縮後的結果。 * **核心差異:** 在 Latent Diffusion Model 中,**雜訊不是加在原始圖像上**,而是加在中間產物,即 **Latent Representation** 上。 * **順向過程 (Diffusion):** 從 Latent Representation 開始加雜訊,直到潛在表徵變成純粹從 Normal Distribution 採樣出來的噪點。 #### B. 條件式去噪與生成 潛在擴散模型在生成時,採用的去噪模型(Noise Predictor)與標準 Diffusion Model 相似,但輸入的內容發生了變化: 1. **Noise Predictor 的輸入:** * 加入雜訊後的 **Latent Representation**。 * 當前進行到的 **Step ID** (代表noise程度)。 * 透過 Text Encoder 處理後的 **文字 Representation**(文字向量)。 2. **生成過程:** 從一個**純粹的雜訊潛在表徵**開始,不斷地將這個潛在表徵、Step ID 和文字 Representation 丟入 Noise Predictor 中,讓其將雜訊去掉。 3. **視覺呈現:** 由於中間產物是潛在表徵,當在生成過程中將這些中間產生的 Latent Representation 透過 Decoder 輸出給使用者看時,你會看到**圖像從模糊漸漸變清晰**的過程。這與直接在像素空間做 Diffusion 時,圖像從完全隨機的白雜訊開始的視覺效果有所不同,因為潛在表徵經過 Decoder 後,即使noise很大,也會呈現出模糊的圖像結構。 --- 其他課程 [【2023 生成式AI】01~03 ChatGPT 原理剖析](https://hackmd.io/@JuitingChen/SyUtDmaalx) [【2023 生成式AI】04~06 文字冒險和機器學習原理](https://hackmd.io/@JuitingChen/S1wwdXa6ge) [【2023 生成式AI】07~08 生成式學習策略和可使用工具的AI](https://hackmd.io/@JuitingChen/BJPQtQpagx) [【2023生成式AI】09~11 Finetuning vs. Prompting](https://hackmd.io/@JuitingChen/H15otQpael) [【2023生成式AI】12~15 大模型 + 大資料 = 神奇結果?](https://hackmd.io/@JuitingChen/rJ1Gi7a6le) [【2023生成式AI】16~18 圖像生成模型 和 Stable Diffusion、DALL-E、Imagen 背後共同的套路](https://hackmd.io/@JuitingChen/HJnB2QTagg) [【2023 生成式AI】19~22 Diffusion Model 原理剖析 ](https://hackmd.io/@JuitingChen/SyBx6mp6xe) [【2023生成式AI】23~25 低成本復刻ChatGPT、ChatGPT自我反省、AI村莊](https://hackmd.io/@JuitingChen/r10hAsrCxe) [【2023生成式AI】26~27 用語言模型來解釋語言模型](https://hackmd.io/@JuitingChen/SJ0aYiwAeg) [【2023生成式AI】28~30 FrugalGPT 用省錢的方式來使用 ChatGPT](https://hackmd.io/@JuitingChen/rypFqnPRll)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up