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

萬字技術(shù)干貨!LLM工程師必讀量化指南,可視化圖解揭秘大模型如何壓縮

人工智能 新聞
面對LLM逐漸膨脹的參數(shù)規(guī)模,沒有H100的開發(fā)者和研究人員們想出了很多彌補方法,「量化」技術(shù)就是其中的一種。這篇可視化指南用各種圖解,將「量化」的基本概念和分支方法進行了全方位總結(jié)。

大語言模型(LLM)通常過于龐大,無法在消費級硬件上運行。這些模型的參數(shù)可能超過數(shù)十億,通常需要顯存較大的GPU來加速推理過程。

因此,越來越多的研究開始關(guān)注如何縮小模型,比如改進訓練方法或使用適配器。該領(lǐng)域的一項主要技術(shù)被稱為量化(quantization)。

ML工程師Maarten Grootendorst撰寫了一篇博客文章,在語言建模背景下專門介紹了量化技術(shù),并通過可視化的方法逐一探索相關(guān)概念,以幫助我們建立對該技術(shù)的直觀理解。

圖片

在這篇博文中,Maarten將探討各種方法、使用案例以及量化背后的原理。

文章目錄以及涵蓋內(nèi)容如下圖所示,主要介紹了訓練后量化(PTQ)以及量化感知訓練(QAT)兩種方法,建議有AI基礎(chǔ)的讀者直接跳轉(zhuǎn)至對稱量化部分:

圖片

第一部分:LLM的「問題」

「大語言模型」就是大在模型參數(shù)量上,規(guī)模通常達到數(shù)十億的級別(其中主要是權(quán)重)。

這些參數(shù)不僅存儲成本相當高,推理階段的計算量也很大。

在推理過程中,激活值是輸入和權(quán)重的乘積,因此權(quán)重數(shù)量越多,激活值也會越大。

圖片

因此,我們希望盡可能高效地表示數(shù)十億個值,從而盡可能減少存儲參數(shù)所需的空間。

讓我們從頭開始,探索數(shù)值是如何表示的,然后再進行優(yōu)化。

如何表示數(shù)值

數(shù)值存儲的形式通常是浮點數(shù)(floting point number,或簡稱為floats):一個帶有小數(shù)點的正數(shù)或負數(shù)。

這些值由每一位(bit)上的二進制數(shù)字表示。

IEEE-754標準描述了每一位上的數(shù)字如何表示具體數(shù)值,具體來說共有三種映射:符號、指數(shù)或小數(shù)(尾數(shù))。

圖片

這三個部分可以結(jié)合起來,根據(jù)一組bit值計算出所表示的數(shù)值:

圖片

使用的位數(shù)越多,表示的數(shù)值值通常越精確,比如FP32形式就能比FP16精確到小數(shù)點后更多位數(shù):

圖片

內(nèi)存限制

可用的位數(shù)越多,不僅數(shù)值越精確,可表示的數(shù)值范圍也越廣。

圖片

給定位數(shù)和表示形式,可表示的數(shù)值區(qū)間稱為動態(tài)范圍(dynamic range),而兩個相鄰值之間的距離稱為精度(precision)。

圖片

這種表達形式的一個巧妙特性在于,我們可以計算出設(shè)備需要多少內(nèi)存來存儲某個給定值。

由于內(nèi)存中的每個字節(jié)含有8位,我們可以為大多數(shù)形式的浮點數(shù)創(chuàng)建一個基本公式——

圖片

在實際應用中,還有更多因素會影響推理過程中所需的顯存/內(nèi)存大小,例如上下文大小和模型架構(gòu)

現(xiàn)在假設(shè)我們有一個包含700億參數(shù)的模型。大多數(shù)模型本身使用32位浮點數(shù)(通常稱為全精度)表示,這需要280GB的內(nèi)存來加載模型。

圖片

但如果能將所有參數(shù)用16位浮點數(shù)表示,所需的內(nèi)存大小就可以直接減少一倍。

因此,將模型參數(shù)的表示位數(shù)最小化(不僅是推理,還有訓練過程)是非常有吸引力的。

然而,這種方法不是沒有代價的。隨著表示位數(shù)減少導致精度降低,模型的準確性通常也會下降。

我們希望在保持準確性的同時減少表示數(shù)值的位數(shù)……此時,量化技術(shù)就派上用場了。

第二部分:量化入門

現(xiàn)在我們知道,量化的目的是將模型參數(shù)的精度從較高位寬(如32位浮點數(shù))降低到較低位寬(如8位整數(shù))。

圖片

在減少表示原始參數(shù)的位數(shù)時,通常也會伴隨一些精度(粒度,granularity)的損失。

為了讓這種效果更直觀,我們可以用照片顏色作為類比。比如,選擇任意圖像(左圖),但只用8種顏色表示(右圖):

圖片

注意看,放大的曲奇餅干看起來比原來更有「顆粒感」。

與之相似,量化的主要目標是減少表示原始參數(shù)所需的比特數(shù)(顏色),同時盡可能保留原始參數(shù)的精度。

常見數(shù)據(jù)類型

首先,讓我們看看常見的數(shù)據(jù)類型以及使用它們替代32位(稱為全精度或FP32)表示的影響。

FP16

首先是一個從32位到16位(稱為半精度或FP16)浮點數(shù)的例子:

圖片

FP16可取的數(shù)值范圍比FP32小得多。

BF16

為了獲得與原始FP32相似的數(shù)值范圍,引入了bfloat 16作為一種「截斷的FP32」類型:

圖片

BF16使用的位數(shù)與FP16相同,但增加了指數(shù)位,因此能取到更廣泛的數(shù)值范圍,常用于深度學習領(lǐng)域。

INT8

進一步減少位數(shù)時,就更接近整數(shù)而非浮點數(shù)的表示方法。比如,從FP32到只具有8位的INT8,只有原始位數(shù)的1/4:

圖片

每次減少位數(shù)時,都會進行映射,將初始的FP32表示「壓縮」到較少的位數(shù)中。

但在實際操作中,我們不需要將整個FP32范圍[-3.4e38, 3.4e38]全部映射到INT8中。我們只需找到一種方法,將實際模型參數(shù)的數(shù)據(jù)范圍映射到INT8中。

常見的壓縮/映射方法可以有對稱量化和非對稱量化兩種,都屬于線性映射。

接下來將要探討的就是從FP32到INT8的量化方法。

對稱量化

在對稱量化中,原始浮點值的范圍被映射到量化空間中以零為中心的對稱范圍,量化前后的范圍都以零為中點。

這意味著,原來浮點空間中的零,映射到量化空間后也恰好是零。

圖片

一種對稱量化的典型例子是最大絕對值(absmax)量化。

給定一個數(shù)值列表,我們?nèi)∑渲凶罡叩慕^對值(α)作為執(zhí)行線性映射的范圍。

圖片

[-127, 127]表示受限范圍(restricted range),未受限范圍是[-128, 127],取決于量化方法

由于這是一個以零為中心的線性映射,公式很簡單。

首先用以下公式計算比例因子(s):

- b是我們要量化到的字節(jié)數(shù)(8)

- α是最高的絕對值

然后,我們使用s來量化輸入x:

圖片

如上圖所示,最大絕對值α為10.8,將FP32映射到INT8時,即有如下公式:

圖片

如果要恢復原始的FP32值,也可以使用先前計算的比例因子(s)來進行反量化。

圖片

先量化,再反量化以恢復原始值,全過程如下所示:

圖片

可以看到某些值,如3.08和3.02,在量化為INT8時都是36。因此進行反量化恢復到FP32時,它們失去了一些精度并且不再可區(qū)分。

這種原始值和反量化值之間的差異被稱為量化誤差。通常,量化結(jié)果的位數(shù)越少,誤差越大。

圖片

非對稱量化

與對稱量化不同,非對稱量化不是以零為中心的對稱。相反,它將浮點范圍內(nèi)的最小值(β)和最大值(α)分別映射到量化范圍的最小值和最大值。

這里我們探討的方法被稱為零點量化(zero-point quantization)。

圖片

注意0的位置是如何移動的。這就是為什么它被稱為非對稱量化。在范圍[-7.59, 10.8]中,最大值和最小值到0的距離不同。

由于零點位置的偏移,我們必須計算INT8范圍內(nèi)的零點才能執(zhí)行線性映射。與之前一樣,我們還必須計算比例因子(s),但使用INT8范圍的差值[-128, 127]。

圖片

由于需要在INT8范圍內(nèi)計算零點(z)以移動權(quán)重,這有點復雜。

像之前一樣,讓我們填入公式:

圖片

為了將量化后的值從INT8反量化回FP32,我們需要使用先前計算的比例因子(s)和零點(z)。

除此之外,反量化很簡單:

圖片

當我們將對稱和非對稱量化并排放置時,可以快速看出兩種方法之間的區(qū)別:

圖片

在上圖中,我們能看到對稱量化的零中心特性與非對稱量化的偏移。

范圍映射和剪裁(Clipping)

在之前的例子中,我們探討了如何將給定向量中的值范圍映射到低位表示。雖然這樣可以映射整個向量值的范圍,但有一個主要缺點,即異常值(outlier)。

想象一下,你有一個包含以下值的向量:

圖片

一個值比其他所有值都大得多,可以被認為是異常值。如果我們映射整個向量的范圍,所有小值將被映射到相同的低位表示,并失去它們的區(qū)分度:

圖片

這是之前使用的absmax方法。如果不進行剪裁,非對稱量化也會發(fā)生同樣的情況

相反,我們可以選擇剪裁某些值。剪裁是指設(shè)置原始值的不同動態(tài)范圍,使所有異常值都被設(shè)為相同的值。

在下面的例子中,我們手動將動態(tài)范圍設(shè)置為[-5, 5],所有超出該范圍的值將被映射到-127或127,無論它們的實際值是多少:

圖片

這種方法的主要優(yōu)點是非異常值的量化誤差顯著減少。然而會導致異常值的量化誤差增加。

校準(Calibration)

上面的例子中,我們隨機將動態(tài)范圍設(shè)置為[-5, 5],但其實應該通過「校準」過程做出決定,找到一個合適的范圍,包含盡可能多的值,同時最小化量化誤差。

校準步驟的具體執(zhí)行對于不同類型的參數(shù)是不一樣的。

權(quán)重(和偏置)

我們可以將大語言模型(LLM)的權(quán)重和偏置(weights & biases)視為靜態(tài)值,因為它們在運行模型之前是已知的。例如,Llama 3的約20GB文件大部分由其權(quán)重和偏置組成。

由于偏置變量的數(shù)量(數(shù)百萬)顯著少于權(quán)重(數(shù)十億),因此偏置通常保持較高精度(如INT16),而量化的主要工作集中在權(quán)重上。

對于已知的靜態(tài)權(quán)重,選擇范圍的校準技術(shù)包括:

- 手動選擇輸入范圍的百分位數(shù)

- 優(yōu)化原始權(quán)重和量化權(quán)重之間的均方誤差(MSE)

- 最小化原始值和量化值之間的熵(KL散度)

圖片

例如,選擇一個百分位數(shù),會導致類似于我們之前看到的剪裁行為。

激活值

在整個大語言模型中不斷更新的輸入通常被稱為激活值(activations)。

圖片

之所以被稱為激活值,因為它們通常會經(jīng)過一些激活函數(shù),如sigmoid或relu

與權(quán)重不同,激活值在推理過程中隨輸入數(shù)據(jù)而變化,因此難以準確量化。

由于這些值在每個隱藏層之后都會更新,因此在推理階段,只有輸入數(shù)據(jù)通過模型后才能得知它們的具體數(shù)值。

圖片

總體來說,有兩種方法用于校準權(quán)重和激活值,應用于模型的不同階段:

- 訓練后量化(Post-Training Quantization,PTQ)

- 顧名思義,即訓練后進行的量化

- 量化感知訓練(Quantization Aware Training,QAT)

- 訓練/微調(diào)期間的量化

第三部分:訓練后量化(PTQ)

訓練后量化(PTQ)是最流行的量化技術(shù)之一。它是在模型訓練完成后,對模型的參數(shù)(包括權(quán)重和激活值)進行量化。

權(quán)重的量化可以采用對稱量化或非對稱量化的方法。

然而,激活值的量化需要經(jīng)過推理階段來獲取其潛在分布,因為我們事先并不知道它們的范圍。

激活值的量化有兩種形式:

- 動態(tài)量化(dynamic quantization)

- 靜態(tài)量化(static quantization)

動態(tài)量化

數(shù)據(jù)通過隱藏層后,其激活值會被收集,比較出每一層的最大值(α)和最小值(β):

圖片

然后利用這些激活值的分布來計算量化輸出所需的零點(zeropoint,z)和比例因子(scale factor,s)值:

圖片

每次數(shù)據(jù)通過新的網(wǎng)絡層時,這個過程都會重復。因此,每一層都有其獨立的z和s值,從而使用不同的量化方案。

靜態(tài)量化

與動態(tài)量化不同,靜態(tài)量化并不是在推理過程中計算零點(zeropoint,z)和比例因子(scale factor,s),而是在推理之前計算這些值。

為了找到這些值,我們會使用一個校準數(shù)據(jù)集,并將其輸入模型以收集這些潛在的激活值分布。

圖片

收集到這些分布之后,就可以計算出在推理過程中進行量化所需的s和z值。

在實際推理時,不會重新計算s和z值,而是在所有激活中全局使用它們來對其進行量化。

總體來說,動態(tài)量化為每個隱藏層計算s和z值,往往更準確。然而,這可能會增加計算時間,因為這些值需要在每次推理時計算。

相反,靜態(tài)量化雖然不如動態(tài)量化準確,但速度更快,因為它已經(jīng)預先知道用于量化的s和z值。

4-bit量化領(lǐng)域

低于8-bit的量化一直是一個挑戰(zhàn),因為每減少一位,量化誤差就會增加。幸運的是,有幾種巧妙的方法可以將位數(shù)減少到6、4,甚至2-bit(盡管通常不建議將位數(shù)降到低于4-bit)。

我們將探討在HuggingFace上常見的兩種方法:

- GPTQ(全模型在GPU上運行)

- GGUF(可能將層卸載到CPU上)

GPTQ

GPTQ可以說是實際應用中最著名的4-bit量化方法之一。

它使用非對稱量化,并逐層進行處理,每層獨立處理后再繼續(xù)處理下一層:

圖片

在這個逐層量化過程中,它首先將層的權(quán)重轉(zhuǎn)換為逆Hessian矩陣。逆Hessian矩陣是模型損失函數(shù)的二階導數(shù),表示模型輸出對每個權(quán)重變化的敏感性。

簡單來說,它本質(zhì)上展示了每個層中權(quán)重的重要性(逆重要性)。

Hessian矩陣中較小值的權(quán)重更為重要,因為這些權(quán)重的微小變化可能導致模型性能的顯著變化。

圖片

在逆Hessian矩陣中,較低的值表示更「重要」的權(quán)重

接下來,我們量化并反量化權(quán)重矩陣的第一行:

圖片

這一過程使我們能夠計算量化誤差(q),我們可以使用之前計算的逆Hessian值(h_1)來加權(quán)這個量化誤差。

本質(zhì)上,我們是在基于權(quán)重的重要性創(chuàng)建加權(quán)量化誤差:

圖片

接下來,我們將這個加權(quán)量化誤差重新分配到該行的其他權(quán)重上。這有助于保持網(wǎng)絡的整體功能和輸出。

例如,如果對第二個權(quán)重(即x_2=0.3)進行此操作,我們會將量化誤差(q)乘以第二個權(quán)重的逆Hessian(h_2)加上去:

圖片

接下來,繼續(xù)對給定行中的第三個權(quán)重進行相同的操作:

圖片

重復這個重新分配加權(quán)量化誤差q的過程,直到所有值都被量化。

這個方法所以有效,是因為權(quán)重通常是相互關(guān)聯(lián)的。因此,當一個權(quán)重有量化誤差時,相關(guān)的權(quán)重會通過逆Hessian進行相應的更新。

GGUF

雖然GPTQ是一種很好的在GPU上運行整個大語言模型(LLM)的量化方法,但如果沒有相應的硬件條件,也可以通過GGUF將LLM的任意層卸載到CPU上。

相當于同時用CPU和GPU運行模型,以彌補顯存(VRAM)不足的情況。

量化方法GGUF經(jīng)常更新,而且依賴于具體的量化位數(shù),但基本原理如下。

首先,給定層的權(quán)重被分成「超級塊」,每個「超級塊」包含一組「子塊」。從這些「子塊」中,我們計算出比例因子(s)和α值:

圖片

為了量化給定的「子塊」,可以使用之前提到的absmax量化,將給定的權(quán)重乘以比例因子(s_sub):

圖片

比例因子s_sub是使用「子塊」中的信息計算的,但用「超級塊」中的信息s_super進行量化:

圖片

總而言之,這種以塊為單位的量化使用「超級塊」的比例因子(s_super)來量化「子塊」的比例因子(s_sub)。

每個比例因子的量化級別可能不同,「超級塊」的比例因子通常比「子塊」有更高的精度。

為了說明這一點,讓我們探討幾個量化級別(2-bit、4-bit和6-bit):

圖片

根據(jù)量化類型,還需要一個額外的最小值(m)來調(diào)整零點,這些與比例因子(s)一樣被量化

第四部分:量化感知訓練(QAT)

第三部分講述了如何在訓練后對模型進行量化。這種方法的缺點在于,沒有考慮到實際的訓練過程。

這就是量化感知訓練(QAT)派上用場的地方。與訓練后量化(PTQ)不同,QAT的目標是在訓練中學習量化過程。

圖片

QAT往往比PTQ更準確,因為在訓練過程中已經(jīng)考慮了量化。其工作原理如下:

在訓練過程中,引入了所謂的「假」量化。比如先將權(quán)重量化為INT4,然后再反量化回FP32:

圖片

這一過程讓模型在訓練階段進行損失計算和權(quán)重更新時,就已經(jīng)考慮到了量化誤差。

如下圖所示,QAT嘗試探索「寬」極小值情況下的損失值,以減少量化誤差,因為「窄」極小值往往會導致更大的量化誤差。

圖片

假設(shè)在反向傳播過程中沒有考慮量化,梯度下降過程就會選擇損失值最小的權(quán)重。然而,如果它處于「窄」極小值中,那將引入更大的量化誤差。

相反,如果我們考慮量化,將在「寬」極小值中選擇一個不同的更新權(quán)重,其量化誤差要小得多。

圖片

因此,盡管PTQ方法在高精度(例如FP32)有較低的損失值,但QAT在低精度(例如INT4)下?lián)p失值也很低,這是我們所追求的。

1-bit時代:BitNet

之前我們看到,將量化精度降低到4-bit已經(jīng)相當小了,但如果我們進一步降低呢?

這就是BitNet的用武之地,它將模型的權(quán)重表示為單個比特,即-1或1,通過將量化過程直接注入到Transformer架構(gòu)中來實現(xiàn)這一點。

Transformer架構(gòu)是大多數(shù)LLM的基礎(chǔ),由涉及線性層的計算組成:

圖片

這些線性層通常以更高的精度表示,如FP16,而且是大多數(shù)權(quán)重所在的位置。

BitNet用BitLinear層替換了這些線性層:

圖片

BitLinear層的工作原理與普通線性層相同,用權(quán)重乘以激活值來計算輸出。

但不同的是,BitLinear層僅用1位表示模型的權(quán)重,使用INT8表示激活值:

圖片

BitLinear層像量化感知訓練(QAT)一樣,在訓練期間執(zhí)行一種「假」量化,以分析權(quán)重和激活值的量化效果:

圖片

讓我們一步步地了解BitLinear。

權(quán)重量化

在訓練過程中,權(quán)重以INT8存儲,然后使用一種稱為符號函數(shù)(signum function)的基本策略將其量化為1位。

本質(zhì)上,它將權(quán)重的分布移動至以0為中心,然后將所有小于0的值分配為-1,將所有大于0的值分配為1:

圖片

此外,它還跟蹤一個值β(平均絕對值),我們將在之后的反量化過程中使用。

激活值量化

為了量化激活值,BitLinear使最大絕對值方法(absmax)將激活值從FP16轉(zhuǎn)換為INT8,因為它們需要以較高的精度進行矩陣乘法(×)。

圖片

此外,它還跟蹤一個值α(最大絕對值),我們將在之后的反量化過程中使用。

反量化

我們跟蹤了α(激活值的最大絕對值)和β(權(quán)重的平均絕對值),這些值將幫助我們將激活值反量化回FP16。

輸出激活值使用{α, γ}重新縮放,以將其反量化到原始精度:

圖片

這個過程相對簡單,并且允許模型僅用兩個值表示,即-1或1。

通過這種方法,作者觀察到,隨著模型規(guī)模的增長,1位訓練和FP16訓練之間的性能差距越來越小。

然而,這僅適用于較大的模型(>30B參數(shù)),較小模型之間的差距仍然很大。

所有LLM都是1.58位

為了改善之前提到的擴展性問題,BitNet 1.58b被引入。

在這種新方法中,模型的每個權(quán)重不僅可以是-1或1,還可以取0,使每個變量成為三元值(ternary)。

有趣的是,僅僅是添加0這個簡單的操作,就大大改進了BitNet,加速了計算過程。

0的力量

為什么添加0是一個重大改進呢?

這與矩陣乘法有關(guān)!

首先,讓我們探討一下矩陣乘法的基本工作原理。

當計算輸出時,我們將權(quán)重矩陣與輸入向量相乘。下面是權(quán)重矩陣的第一層的第一行乘法的可視化:

圖片

這種乘法涉及兩個動作,將單個權(quán)重與輸入相乘,然后將它們?nèi)肯嗉印?/span>

相比之下,BitNet 1.58b設(shè)法避免了乘法的動作,因為三值權(quán)重本質(zhì)上告訴你以下內(nèi)容:

- 1:我想加上這個值

- 0:我不想要這個值

- -1:我想減去這個值

因此,如果你的權(quán)重被量化到1.58 bit,你只需要執(zhí)行加法:

圖片

這不僅可以顯著加快計算速度,還允許特征過濾。

將給定的權(quán)重設(shè)置為0就相當于忽略了這個輸入,而不是像1-bit那樣,表示加上或減去輸入值。

量化

為了執(zhí)行權(quán)重量化,BitNet 1.58b使用平均絕對值量化(absmean),這是我們之前見過的最大絕對值量化(absmax)的變體。

它只是壓縮權(quán)重的分布并使用絕對均值(α)來量化值。然后將它們四舍五入為-1、0或1:

圖片

與BitNet相比,激活值量化是相同的,除了一個方面:不是將激活值縮放到范圍[0, 2??1],而是使用最大絕對值方法縮放到[-2??1, 2??1]。

總結(jié)一下,1.58-bit量化主要涉及兩個技巧:

- 添加0以創(chuàng)建三值表示[-1, 0, 1]

- 權(quán)重的絕對均值量化

BitNet論文中有這樣的結(jié)論:「13B BitNet b1.58在延遲、內(nèi)存使用和能耗方面比3B FP16 LLM更高效。」

圖片

論文地址:https://arxiv.org/abs/2402.17764

由于只有1.58個計算效率高的bit,我們得到了輕量級模型。

責任編輯:張燕妮 來源: 新智元
相關(guān)推薦

2024-01-15 08:17:00

模型技術(shù)

2025-01-07 13:22:58

2024-07-19 08:34:18

2010-09-13 17:38:47

Google的系統(tǒng)工程

2023-12-04 13:38:55

模型3D可視化

2023-03-30 08:28:57

explain關(guān)鍵字MySQL

2024-09-11 15:59:31

LLM.int8()大模型量化

2020-10-26 15:33:13

可視化數(shù)據(jù)項目

2022-09-28 09:12:16

HBase分布式數(shù)據(jù)庫數(shù)據(jù)庫

2024-02-01 08:34:30

大模型推理框架NVIDIA

2020-09-21 10:50:24

Java多線程代碼

2018-06-15 15:50:34

技術(shù)

2015-08-13 13:48:50

數(shù)據(jù)中心

2016-05-16 14:18:00

2018-01-02 09:17:57

2022-02-15 18:45:35

Linux進程調(diào)度器

2022-07-04 15:56:55

智能方案

2020-11-17 08:08:34

分庫分表

2022-07-19 16:03:14

KubernetesLinux

2025-04-23 08:31:26

Java并發(fā)框架
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 成人亚洲综合 | 色婷婷久久 | 国产成人一区二区三区 | 亚洲在线一区二区 | 欧美一区二区三区在线观看 | 午夜精品久久久久久久久久久久久 | 日韩三级视频 | 欧美区日韩区 | 成人在线观看网站 | 久久a久久 | 婷婷久久网 | 56pao在线 | 成人伊人 | 国产精品a久久久久 | 亚洲v日韩v综合v精品v | 成人影院午夜 | 久久久高清| 国产精品视频yy9299一区 | 999视频在线播放 | 欧美老少妇一级特黄一片 | 欧美另类视频 | 日本高清中文字幕 | 成人国产精品久久久 | 精品不卡 | 少妇无套高潮一二三区 | 久久久久久综合 | 福利网址 | 91精品国产综合久久国产大片 | 国产一级免费在线观看 | aaaaa毛片 | 午夜国产羞羞视频免费网站 | 国产精品爱久久久久久久 | 国产精品黄视频 | 日韩在线免费播放 | jvid精品资源在线观看 | 日韩视频中文字幕 | 日韩av一区二区在线观看 | 在线看av的网址 | 国产丝袜一区二区三区免费视频 | 欧洲一级毛片 | 91美女视频 |