精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

從零實現大模型-GPT2指令微調 原創

發布于 2024-6-20 13:06
瀏覽
0收藏


從零實現大模型-GPT2指令微調 -AI.x社區


??The Annotated Transformer注釋加量版??

??The Annotated GPT2注釋加量版??

??The Annotated BERT注釋加量版??


前面三篇文章實現了Transformer、BERT以及GPT2的預訓練過程,也就是上圖中的Stage1和Stage2,并通過打印數據信息可視化了預訓練和推理過程。


從零實現大模型-GPT2指令微調 -AI.x社區


此時的GPT2雖然能預測下一個詞,但并不能很好地跟隨人類指令,如果想讓它翻譯就能翻譯,想讓它總結就能總結,接下來還要進行指令微調。

本文我們基于此前的GPT2預訓練模型進行指令微調。

下圖是本文的內容概括。

從零實現大模型-GPT2指令微調 -AI.x社區

前三篇文章以及本文完整代碼都已整理到一個路徑下,請結合代碼閱讀本文內容。

ttps://github.com/AIDajiangtang/LLM-from-scratch
https://github.com/AIDajiangtang/LLM-from-scratch/blob/main/GPT2_instruction_finetuning_from_scratch.ipynb


0.下載訓練數據

import json
import os
import urllib




def download_and_load_file(file_path, url):


    if not os.path.exists(file_path):
        with urllib.request.urlopen(url) as response:
            text_data = response.read().decode('utf-8')
        with open(file_path, "w", encoding="utf-8") as file:
            file.write(text_data)
    else:
        with open(file_path, "r", encoding="utf-8") as file:
            text_data = file.read()


    with open(file_path, "r") as file:
        data = json.load(file)


    return data




file_path = "instruction-data.json"
url = "https://raw.githubusercontent.com/rasbt/LLMs-from-scratch/main/ch07/01_main-chapter-code/instruction-data.json"


data = download_and_load_file(file_path, url)
print("Number of entries:", len(data))

該指令微調訓練數據包含1100條訓練樣本,下面打印其中一條。

{'instruction': 'Identify the correct spelling of the following word.', 'input': 'Ocassion', 'output': "The correct spelling is 'Occasion.'"}

指令微調是一種有監督學習方法,訓練數據由指令、輸入和輸出組成,然后將這三部分格式化成某種prompt格式,下圖是兩種常見的格式化方法。

從零實現大模型-GPT2指令微調 -AI.x社區

本文我們采用Alpaca-style prompt格式化方法。

指令微調與預訓練,除了訓練數據,其它基本一致。

def format_input(entry):
    instruction_text = (
        f"Below is an instruction that describes a task. "
        f"Write a response that appropriately completes the request."
        f"\n\n### Instruction:\n{entry['instruction']}"
    )


    input_text = f"\n\n### Input:\n{entry['input']}" if entry["input"] else ""


    return instruction_text + input_text

接下來我們打印一條格式化后的樣本。

model_input = format_input(data[50])
desired_response = f"\n\n### Response:\n{data[50]['output']}"


print(model_input + desired_response)

Below is an instruction that describes a task. Write a response that appropriately completes the request.
### Instruction:
Identify the correct spelling of the following word.


### Input:
Ocassion


### Response:
The correct spelling is 'Occasion.'

其中輸入并不是必須的。

### Instruction:
What is an antonym of 'complicated'?


### Response:
An antonym of 'complicated' is 'simple'.

接下來將這1100條訓練數據劃分為訓練集、測試集和驗證集。

train_portion = int(len(data) * 0.85)  # 85% for training
test_portion = int(len(data) * 0.1)   # 10% for testing
val_portion = len(data) - train_portion - test_portion  # Remaining 5% for validation


train_data = data[:train_portion]
test_data = data[train_portion:train_portion + test_portion]
val_data = data[train_portion + test_portion:]


1.準備訓練數據

準備訓練數據過程可分為下面幾步。

從零實現大模型-GPT2指令微調 -AI.x社區

先格式化輸入,然后轉換為token id。

從零實現大模型-GPT2指令微調 -AI.x社區

import torch
from torch.utils.data import Dataset




class InstructionDataset(Dataset):
    def __init__(self, data, tokenizer):
        self.data = data


        # Pre-tokenize texts
        self.encoded_texts = []
        for entry in data:
            instruction_plus_input = format_input(entry)
            response_text = f"\n\n### Response:\n{entry['output']}"
            full_text = instruction_plus_input + response_text
            self.encoded_texts.append(
                tokenizer.encode(full_text)
            )


    def __getitem__(self, index):
        return self.encoded_texts[index]


    def __len__(self):
        return len(self.data)


import tiktoken
tokenizer = tiktoken.get_encoding("gpt2")


print(tokenizer.encode("<|endoftext|>", allowed_special={"<|endoftext|>"}))

[50256]

將樣本劃分成batches,找到每個batch中最長文本長度作為整個batch的長度,將其它數據padding到統一長度,<|endoftext|>(50256)作為padding token。

從零實現大模型-GPT2指令微調 -AI.x社區

將輸入向右移動一位構造標簽。

從零實現大模型-GPT2指令微調 -AI.x社區

最后將標簽中的padding token替換成-100,使其計算損失時忽略該padding token,但要保留一個<|endoftext|作為結束符,

從零實現大模型-GPT2指令微調 -AI.x社區

def custom_collate_fn(
    batch,
    pad_token_id=50256,
    ignore_index=-100,
    allowed_max_length=None,
    device="cpu"
):
    # Find the longest sequence in the batch
    batch_max_length = max(len(item)+1 for item in batch)


    # Pad and prepare inputs and targets
    inputs_lst, targets_lst = [], []


    for item in batch:
        new_item = item.copy()
        # Add an <|endoftext|> token
        new_item += [pad_token_id]
        # Pad sequences to max_length
        padded = new_item + [pad_token_id] * (batch_max_length - len(new_item))
        inputs = torch.tensor(padded[:-1])  # Truncate the last token for inputs
        targets = torch.tensor(padded[1:])  # Shift +1 to the right for targets


        # New: Replace all but the first padding tokens in targets by ignore_index
        mask = targets == pad_token_id
        indices = torch.nonzero(mask).squeeze()
        if indices.numel() > 1:
            targets[indices[1:]] = ignore_index


        # New: Optionally truncate to maximum sequence length
        if allowed_max_length is not None:
            inputs = inputs[:allowed_max_length]
            targets = targets[:allowed_max_length]


        inputs_lst.append(inputs)
        targets_lst.append(targets)


    # Convert list of inputs and targets to tensors and transfer to target device
    inputs_tensor = torch.stack(inputs_lst).to(device)
    targets_tensor = torch.stack(targets_lst).to(device)


    return inputs_tensor, targets_tensor

在實際中,通常還會將標簽中非輸出的內容替換成-100,使其不參與損失計算。

從零實現大模型-GPT2指令微調 -AI.x社區

from torch.utils.data import DataLoader




num_workers = 0
batch_size = 8


torch.manual_seed(123)


train_dataset = InstructionDataset(train_data, tokenizer)
train_loader = DataLoader(
    train_dataset,
    batch_size=batch_size,
    collate_fn=customized_collate_fn,
    shuffle=True,
    drop_last=True
)

設置batch_size = 8,接下來查看每個batch的輸入和標簽的數據維度。

print("Train loader:")
for inputs, targets in train_loader:
    print(inputs.shape, targets.shape)


Train loader:
torch.Size([8, 61]) torch.Size([8, 61])
torch.Size([8, 76]) torch.Size([8, 76])
torch.Size([8, 73]) torch.Size([8, 73])
torch.Size([8, 68]) torch.Size([8, 68])
torch.Size([8, 65]) torch.Size([8, 65])
torch.Size([8, 72]) torch.Size([8, 72])
torch.Size([8, 80]) torch.Size([8, 80])
torch.Size([8, 67]) torch.Size([8, 67])
torch.Size([8, 62]) torch.Size([8, 62])
torch.Size([8, 75]) torch.Size([8, 75])
torch.Size([8, 62]) torch.Size([8, 62])
torch.Size([8, 68]) torch.Size([8, 68])
torch.Size([8, 67]) torch.Size([8, 67])
torch.Size([8, 77]) torch.Size([8, 77])
torch.Size([8, 69]) torch.Size([8, 69])
torch.Size([8, 79]) torch.Size([8, 79])
torch.Size([8, 71]) torch.Size([8, 71])
torch.Size([8, 66]) torch.Size([8, 66])
torch.Size([8, 83]) torch.Size([8, 83])

打印一個樣本,查看是否正確。

輸入:
tensor([21106,   318,   281, 12064,   326,  8477,   257,  4876,    13, 19430,
          257,  2882,   326, 20431, 32543,   262,  2581,    13,   198,   198,
        21017, 46486,    25,   198, 30003,  6525,   262,  6827,  1262,   257,
          985,   576,    13,   198,   198, 21017, 23412,    25,   198,   464,
         5156,   318,   845, 13779,    13,   198,   198, 21017, 18261,    25,
          198,   464,  5156,   318,   355, 13779,   355,   257,  4936,    13,
        50256, 50256, 50256, 50256, 50256, 50256, 50256, 50256, 50256],
       device='cuda:0')

標簽:
tensor([  318,   281, 12064,   326,  8477,   257,  4876,    13, 19430,   257,
         2882,   326, 20431, 32543,   262,  2581,    13,   198,   198, 21017,
        46486,    25,   198, 30003,  6525,   262,  6827,  1262,   257,   985,
          576,    13,   198,   198, 21017, 23412,    25,   198,   464,  5156,
          318,   845, 13779,    13,   198,   198, 21017, 18261,    25,   198,
          464,  5156,   318,   355, 13779,   355,   257,  4936,    13, 50256,
         -100,  -100,  -100,  -100,  -100,  -100,  -100,  -100,  -100],
       device='cuda:0')

2.加載預訓練模型

??從零開始GPT2預訓練??

加載GPT2預訓練模型。

from gpt_download import download_and_load_gpt2
from previous_chapters import GPTModel, load_weights_into_gpt




BASE_CONFIG = {
    "vocab_size": 50257,     # Vocabulary size
    "context_length": 1024,  # Context length
    "drop_rate": 0.0,        # Dropout rate
    "qkv_bias": True         # Query-key-value bias
}


model_configs = {
    "gpt2-small (124M)": {"emb_dim": 768, "n_layers": 12, "n_heads": 12},
    "gpt2-medium (355M)": {"emb_dim": 1024, "n_layers": 24, "n_heads": 16},
    "gpt2-large (774M)": {"emb_dim": 1280, "n_layers": 36, "n_heads": 20},
    "gpt2-xl (1558M)": {"emb_dim": 1600, "n_layers": 48, "n_heads": 25},
}


CHOOSE_MODEL = "gpt2-medium (355M)"


BASE_CONFIG.update(model_configs[CHOOSE_MODEL])


model_size = CHOOSE_MODEL.split(" ")[-1].lstrip("(").rstrip(")")
settings, params = download_and_load_gpt2(model_size=model_size, models_dir="gpt2")


model = GPTModel(BASE_CONFIG)
load_weights_into_gpt(model, params)
model.eval();

在開始指令微調前,先驗證下預訓練模型的效果。

torch.manual_seed(123)


input_text = format_input(val_data[0])
print(input_text)

Below is an instruction that describes a task. Write a response that appropriately completes the request.

### Instruction:
Convert the active sentence to passive: 'The chef cooks the meal every day.'


from previous_chapters import (
    generate,
    text_to_token_ids,
    token_ids_to_text
)


token_ids = generate(
    model=model,
    idx=text_to_token_ids(input_text, tokenizer),
    max_new_tokens=35,
    context_size=BASE_CONFIG["context_length"],
    eos_id=50256,
)
generated_text = token_ids_to_text(token_ids, tokenizer)




response_text = generated_text[len(input_text):].strip()
print(response_text)

### Response:

The chef cooks the meal every day.

### Instruction:

Convert the active sentence to passive: 'The chef cooks the

通過結果可知,預訓練模型并沒有跟隨人類指令,雖然有輸出,但只是簡單的復制了輸入和指令內容。

3.指令微調

前面我們說過,除了構造訓練數據外,指令微調過程和預訓練過程基本一致。

3.1詞嵌入

從零實現大模型-GPT2指令微調 -AI.x社區

假設第一個batch的輸入X和標簽的維度[8, 61],接下來將[8, 61]個token ids轉換成詞嵌入,根據超參數設置:"emb_dim": 768,詞嵌入層輸出[8, 61,768]。

另外,在計算注意力時,沒有考慮token之間的相對位置,所以要在詞嵌入上加一個位置編碼,位置編碼向量維度與詞嵌入維度相同。

最終輸出[8, 61,768]維詞嵌入。

3.2.TransformerBlock

從零實現大模型-GPT2指令微調 -AI.x社區


根據超參數設置"n_layers": 12,模型會經過12個結構相同,但參數獨立的TransformerBlock模塊。

TransformerBlock是由MultiHeadAttention、FeedForward和LayerNorm構成。

接下來我們看看數據是如何流經這些層的。

3.3.MultiHeadAttention

輸入的詞嵌入[8, 61,768]先經過三個矩陣[768, 768]變換,分別得到q、k、v,維度都是[8, 61,768]。

根據超參數設置"n_heads": 12,將q、k、v reshape成[8, 61, 12,64],再轉置成[8, 12,61, 64]。將原始768維詞嵌入劃分到12個頭中,每個頭64維,這就實現了多頭注意力機制。


從零實現大模型-GPT2指令微調 -AI.x社區

然后計算每個頭的注意力,注意力分數矩陣維度[8, 12, 61, 61]。

為了防止看到未來時刻的內容,構造一個上三角掩碼矩陣[61, 61],其對角線以上的部分設置True, 再將注意力分數矩陣中對應掩碼矩陣為True的位置設置為負無窮,這樣softmax 之后接近于零,以屏蔽未來位置的注意力得分。

self.register_buffer(
        'mask',
        torch.triu(torch.ones(
            context_length,             # 61
            context_length,             # 61
          ), diagnotallow=1)
    )
    mask_bool = self.mask.bool()[:num_tokens, :num_tokens]


    # Mask the attention scores
    attention_scores.masked_fill_(mask_bool, -torch.inf)


從零實現大模型-GPT2指令微調 -AI.x社區

然后將注意力分數矩陣[8, 12, 61, 61]與值矩陣v[8, 12,61, 64]相乘,輸出[8, 12,61, 64]。

最后將多個頭的輸出通過轉置,reshape成[8, 61, 768],再經過一個線性層[768, 768]輸出[8, 61, 768],最終與輸入進行殘差鏈接輸出[8, 61, 768]。

3.4.LaynerNorm

LaynerNorm的目的是為了計算穩定,不改變維度,LaynerNorm層的輸入輸出維度均是[8, 61, 768]。

3.5.FeedForward

FeedForward是一個MLP層,前面LaynerNorm層的輸出[8, 61, 768],8*61個詞嵌入并行通過MLP層,先升維到4*768,再恢復到768,中間使用GELU非線性激活函數。

MLP層不會改變輸入維度[8, 61, 768],但會通過非線性變換會進一步修改詞嵌入的值,以次提升模型的表示能力,生成更高層次的抽象特征。

3.6.輸出

從零實現大模型-GPT2指令微調 -AI.x社區

MLP層的輸出[8, 61, 768]先經過一個LaynerNorm進行平滑操作。

最后8*61個token并行經過一個輸出線性層[768, n_vcab],將[8, 61, 768]映射成[8, 61, n_vcab],n_vcab為詞表大小。

也就是每個token都會輸出一個概率分布,這n_vcab個概率值表示下一個token屬于詞表中n_vcab個詞的概率。

3.7.計算損失

訓練過程中需要通過計算損失來更新參數,如何根據輸出[8, 61, n_vcab]計算損失呢?

在準備訓練數據時已經構造了標簽,維度與輸入X一致,也是[8, 61]。

def calc_loss_batch(input_batch, target_batch, model, device):
  """
  Calculates the loss for a single batch.
  """
  input_batch = input_batch.to(device)
  target_batch = target_batch.to(device)


  # Run the model
  logits = model(input_batch)
  print("target_batch loss")
  print(target_batch.flatten().shape)
  print("logits.flatten(0, 1)")
  print(logits.flatten(0, 1).shape)
  # Calculate the loss
  loss = torch.nn.functional.cross_entropy(
      logits.flatten(0, 1),
      target_batch.flatten(),
  )
  return loss

input_batch是輸入X,維度[8, 61],target_batch是標簽,維度[8, 61],輸入經過模型后輸出[8, 61, n_vcab],展平后[488, n_vcab],標簽展平后[488],每個元素表示詞表中位置。

cross_entropy估計是根據這[488]位置構造one-hot編碼,然后與輸出logits計算損失值。


本文轉載自公眾號人工智能大講堂 

原文鏈接:??https://mp.weixin.qq.com/s/n7RYWlM3N5weHC8L10mAvw??

?著作權歸作者所有,如需轉載,請注明出處,否則將追究法律責任
收藏
回復
舉報
回復
相關推薦
在线观看xxx| 希岛爱理中文字幕| 偷拍精品精品一区二区三区| 国产精品一二三| 九九精品视频在线观看| 一区二区三区四区影院| 日韩伦理在线| 中文在线资源观看网站视频免费不卡| 国产精品第二页| 精品亚洲乱码一区二区 | 久久久久久久久99精品大| 91精品综合久久久久久| 精品视频在线观看一区二区| 香蕉视频免费在线看| 男人操女人的视频在线观看欧美| 久久亚洲精品网站| 国产精品九九视频| 国产精品传媒麻豆hd| 夜夜亚洲天天久久| 日韩电影大全在线观看| 精品人妻一区二区三区三区四区| 国产精品一二| 久久久精品亚洲| 亚洲久久久久久| 日韩毛片免费看| 精品久久久久久亚洲国产300| 色一情一乱一伦一区二区三区| 国产精品一区二区av白丝下载| 亚洲精品字幕| www日韩欧美| 亚洲AV无码国产精品| 91成人在线网站| 午夜精品久久一牛影视| 中文字幕一区二区三区四区五区 | 日日欢夜夜爽一区| 欧美精品久久久久久久久| 91l九色lporny| 一区二区亚洲视频| 欧美另类videos死尸| 日本一道本久久| 97caopor国产在线视频| 久久精品视频免费观看| 国产精品国产亚洲精品看不卡15| 中文字幕资源网| 亚洲一区黄色| 欧美激情亚洲另类| 国产精品国产精品88| 国产一区三区在线播放| 亚洲国模精品私拍| 精品人妻人人做人人爽夜夜爽| 成人精品国产| 色94色欧美sute亚洲线路一ni| h无码动漫在线观看| 二区在线播放| 国产精品久久久99| 色婷婷精品国产一区二区三区| 五月婷婷丁香六月| www.色精品| 成人淫片在线看| 9i看片成人免费看片| 一区二区电影| 最近2019中文字幕mv免费看| 国产人妻人伦精品1国产丝袜 | 国产精品青青草| 国产黄色大片网站| 国产精品一二三四五| 成人精品视频在线| 一级黄色免费看| 另类小说一区二区三区| 国产精品99蜜臀久久不卡二区| 伦av综合一区| 久久久蜜桃一区二区人| 日本乱人伦a精品| 少妇高潮av久久久久久| 久久在线精品| 欧美最猛性xxxx| 久久久久久久久久久久久av| 久久综合影视| 国产精品久久精品| 一二三四区视频| 国产九色精品成人porny| 91久久在线视频| www.看毛片| 成人99免费视频| 美女一区视频| 69av亚洲| 亚洲免费在线视频| 黄色一级片在线看| 日韩欧美精品一区二区三区| 五月婷婷色综合| 国产精品www在线观看| 午夜成年人在线免费视频| 亚洲精品中文字幕乱码三区 | 色综合久久久无码中文字幕波多| 亚洲日本va| 精品夜色国产国偷在线| 人人妻人人澡人人爽| 天天射—综合中文网| 日韩中文字幕在线观看| 青青草原在线免费观看| 亚洲精品乱码| 国产精品国语对白| 国产wwwxxx| 91网站最新网址| 亚洲午夜精品福利| 成人日韩欧美| 精品成人久久av| 韩国中文字幕av| 亚洲超碰在线观看| 亚洲精选一区二区| 91制片厂在线| 亚洲午夜久久久久久尤物| 国产精品第三页| 国产高中女学生第一次| 久久久久久亚洲综合影院红桃| 一区二区三区在线观看www| 丰乳肥臀在线| 欧美三级三级三级| 亚洲图片欧美另类| 色135综合网| 久久久亚洲成人| 国产精品欧美综合| 成人黄色av网站在线| 视频一区二区在线| 91吃瓜在线观看| 91精品久久久久久久99蜜桃| 一本色道综合久久欧美日韩精品| 久久亚洲国产| 国产99视频精品免视看7| 性一交一乱一乱一视频| 久久蜜桃一区二区| 超碰10000| 黄视频网站在线观看| 欧美电视剧在线看免费| 亚洲久草在线视频| 成人免费aaa| 精品视频在线观看网站| 亚洲视频在线免费观看| 五月天综合在线| 国产乱人伦偷精品视频不卡| 日韩啊v在线| 中文字幕不卡三区视频| 欧美一区二区三级| 自拍偷拍你懂的| 亚洲三级免费| 亚洲精品免费网站| av一本在线| 欧美性猛交xxxx乱大交退制版| 中出视频在线观看| 亚洲人人精品| 成人精品一二区| 国产三级在线播放| 一本色道a无线码一区v| 中文字幕在线视频播放| 在线成人激情| 成人黄色激情网| 99reav在线| 欧美综合久久久| 欧美色图亚洲激情| 国产模特精品视频久久久久| 精品一区二区三区日本| caoporn视频在线观看| 欧美成人猛片aaaaaaa| 神马午夜精品91| 久久99国产精品免费网站| 婷婷亚洲婷婷综合色香五月| 日韩在线短视频| 国产亚洲欧美日韩美女| 免费视频网站在线观看入口| 91老司机福利 在线| 亚洲 欧美 日韩 国产综合 在线| 久久九九热re6这里有精品| 欧美激情中文网| 亚洲乱色熟女一区二区三区| 一区二区三区在线免费| 亚洲熟女一区二区三区| 在线观看的日韩av| 精品一区二区三区视频日产| 老司机深夜福利在线观看| 国产丝袜一区二区三区| www.国产毛片| 欧美国产一区二区| 嫩草视频免费在线观看| 亚洲最大av| 国产精品中出一区二区三区| 波多野结衣视频一区二区| 亚洲欧洲中文天堂| 亚洲字幕av一区二区三区四区| 中文字幕亚洲欧美在线不卡| 女人扒开双腿让男人捅 | 麻豆网站在线看| 91精品欧美综合在线观看最新| wwwav国产| 99久久免费视频.com| 国产裸体免费无遮挡| 欧美成人自拍| 懂色av一区二区三区在线播放| av在线最新| 中文字幕av一区二区| 亚洲天堂中文在线| 日韩美女精品在线| 国产免费a级片| 久久xxxx精品视频| 亚洲欧美久久久久一区二区三区| 超碰精品在线| 欧美亚洲另类制服自拍| 日本在线观看网站| 精品国产伦一区二区三区观看方式 | 自拍偷拍亚洲欧美| 免费激情视频网站| 欧美三区在线观看| 免费中文字幕日韩| 国产成人精品三级| 日本在线xxx| 日本不卡高清| 2022国产精品| 欧美日韩伦理一区二区| 91精品国产精品| 伦xxxx在线| 亚洲欧美日韩国产中文专区| 国产精品视频第一页| 欧美日韩黄色大片| 青青草激情视频| 日本一区二区高清| 亚洲天堂2024| 韩日精品视频一区| 中文字幕无码不卡免费视频| 欧美福利影院| 亚洲欧美日韩另类精品一区二区三区| 美女视频亚洲色图| 91亚洲精品丁香在线观看| 欧美91在线|欧美| 欧美在线视频一区二区| 国产丝袜视频在线播放| 久久精品2019中文字幕| 国产免费av在线| 亚洲国产高清福利视频| 精品国产免费无码久久久| 欧美系列在线观看| 老熟妇仑乱一区二区av| 午夜国产不卡在线观看视频| 欧美老熟妇一区二区三区| 国产午夜精品美女毛片视频| 美女又爽又黄视频毛茸茸| 波多野结衣亚洲一区| 国产sm在线观看| 国产麻豆视频一区二区| 天天摸天天舔天天操| 日韩av一二三| 无码内射中文字幕岛国片| 国产亚洲一级| 国内性生活视频| 99精品视频网| 日本天堂免费a| 外国成人免费视频| 中文字幕精品一区日韩| 国产精品99久久| 亚洲三区四区| 久久亚洲国产| 大地资源第二页在线观看高清版| 欧美手机视频| 欧美中日韩免费视频| 亚洲国产国产| 高清视频一区| 一区二区三区视频免费视频观看网站| 7777精品久久久大香线蕉小说| yiren22亚洲综合| 国产精品爱啪在线线免费观看| 美女精品视频| 97成人超碰免| 高清电影一区| 国产精品久久久亚洲| 成人国产一区| 亚洲一区二区三| 视频在线亚洲| 国产三级精品在线不卡| 国产乱人伦精品一区| 久久精品中文字幕一区二区三区 | 欧美日韩国产a| 91久久久久久久久久久久| 337p亚洲精品色噜噜噜| 亚洲av无码一区二区乱子伦| 亚洲变态欧美另类捆绑| 秋霞av在线| 日韩在线观看免费全| av毛片在线免费| 亚州精品天堂中文字幕| 欧美××××黑人××性爽| 国产日本欧美一区二区三区| 国产精品美女久久久久人| 国产精品美女黄网| 亚洲色图美女| 久久久国产精华液999999| 欧美成人高清| 久久久精品在线视频| 蜜臀久久99精品久久久画质超高清| 黄色一级片免费的| 波多野结衣精品在线| 色欲AV无码精品一区二区久久| 亚洲人精品午夜| 国产性xxxx高清| 欧美三级日韩三级| 亚洲精品国产suv一区| 亚洲三级免费看| 国产传媒在线播放| 欧美在线亚洲一区| 99视频有精品高清视频| 精品一区二区不卡| 午夜精品一区二区三区国产 | 美女精品导航| 国产精品久久久久免费a∨大胸| 91精品啪在线观看国产爱臀| 日本一区二区久久精品| 欧美午夜一区| 亚洲老女人av| 99re这里只有精品首页| 国产老头老太做爰视频| 一区二区久久久| 国产又粗又长又黄| 亚洲免费伊人电影在线观看av| 尤物在线网址| 国产精品欧美激情| 激情小说亚洲色图| 欧美少妇一区二区三区| 日韩高清中文字幕一区| 久久久久久久无码| 亚洲精品老司机| 中文字幕在线视频第一页| 日韩精品中文字幕在线播放| 风间由美一区| 78色国产精品| caoporn成人| 欧美aaa在线观看| 免费av成人在线| 国产精品天天干| 欧美日韩精品中文字幕| 亚洲国产综合网| 欧美大奶子在线| 日本成人一区二区| 视频三区二区一区| 日本免费新一区视频| 亚洲精品乱码久久久久久不卡| 亚洲精品第1页| 国产精品热久久| 日韩中文在线中文网三级| 国产在线|日韩| 欧美一区二区在线视频观看| 国产一区二区三区久久| 中文字幕在线永久| 亚洲国产一区视频| 成人乱码一区二区三区| 色综合久久精品亚洲国产| 国产精品亚洲一区二区在线观看| 亚洲精品一区二区三区樱花| 日韩高清在线观看| 中文字幕av久久爽一区| 色吊一区二区三区| 亚洲 小说区 图片区 都市| 久久久久久一区二区三区| 欧州一区二区三区| 日韩五码在线观看| 99久久99久久精品国产片果冻| 久久久久久久伊人| 亚洲精品国产综合久久| 精品极品在线| 久久另类ts人妖一区二区| 性8sex亚洲区入口| 中文字幕成人动漫| 欧美日韩一区二区欧美激情| 性开放的欧美大片| 成人免费观看a| 欧美精品aa| 欧美在线一级片| 91国模大尺度私拍在线视频| 自拍视频在线网| 成人黄在线观看| 欧美日韩精品| 99国产精品免费视频| 一个色妞综合视频在线观看| av男人天堂网| 欧美一区二区三区……| 色喇叭免费久久综合网| 污污视频在线免费| 亚洲一级二级三级在线免费观看| 天天操天天干天天爽| 欧美专区中文字幕| 日韩欧美字幕| 成人一区二区三区仙踪林| 调教+趴+乳夹+国产+精品| 青草久久伊人| 成人中文字幕+乱码+中文字幕| 欧美日韩亚洲一区二区三区在线| 97香蕉碰碰人妻国产欧美| 欧美亚洲一区三区| 日本一级理论片在线大全| 欧美18视频| 国产美女在线精品| 精品久久免费视频| 中文字幕国产精品| 中文字幕一区图|