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

RAG系列:切分優化 - 基于句子余弦距離的語義切分

人工智能
本文介紹了一種更智能的切分方法 - 基于句子余弦距離的語義切分,并通過 langchain-experimental 中的 SemanticChunker 的源碼來帶大家了解了語義切分的實現原理。

引言

傳統的文檔切分方法通常采用基于特定字符和固定長度的切分策略,這種方法雖然實現簡單,但在實際應用中容易割裂完整的語義單元,導致后續的信息檢索與理解受到影響。

相比之下,一種更智能的切分方法是基于句子余弦距離的語義切分。它不再依據特定字符和固定長度進行機械切分,而是對每個句子進行 embedding,以此來計算相鄰句子的余弦距離,再通過算法算出一個相對合理的切分點(某個距離值),最后將不大于該閾值的相鄰句子聚合在一起作為一個文檔塊,從而實現文檔語義切分。

例如 句子_1、句子_2、句子_3 之間的余弦距離都小于該閾值,而 句子_3 與 句子_4 的余弦距離大于該閾值,則在 句子_3 和 句子_4 之間增加切分點,最終的切分結果就是把 句子_1、句子_2、句子_3 聚合在一個文檔塊中,句子_4 在其它的文檔塊中。

實現原理

基于余弦距離的語義切分大致分為以下5個步驟:

圖片

langchain-experimental中的 SemanticChunker[1] 實現了基于余弦距離的語義切分,因此本文我將通過 SemanticChunker 的源碼來帶大家了解語義切分的實現原理。

以下是 SemanticChunker 的初始化參數,后面根據不同步驟所需要的參數來了解這些參數的具體作用。

class SemanticChunker(
    # 向量模型
    embeddings: Embeddings,
    # 向前向后取 buffer_size 個句子一起 embedding
    buffer_size: int = 1, 
    # 是否在元數據添加開始切分的位置(以文檔字符長度計算)
    add_start_index: bool = False,
    # 切分點計算方法
    breakpoint_threshold_type: BreakpointThresholdType = "percentile",
    # 切分點計算閾值
    breakpoint_threshold_amount: float | None = None,
    # 切分后的文檔塊數量
    number_of_chunks: int | None = None,
    # 句子切分規則
    sentence_split_regex: str = r"(?<=[.?!])\s+",
    # 最小文檔塊大小
    min_chunk_size: int | None = None
)

句子切分

這一步是通過特定規則將文檔切分為一個個句子,在 SemanticChunker 中通過參數 sentence_split_regex 來設置規則進行切分,默認值為 r"(?<=[.?!])\s+",這是以英文的句號、問號、感嘆號來進行切分的,而且是對比較規范的英文行文,也就是這三種標點后還跟空白字符的。如果要對中文文檔切分,那就需要將這個正則表達式替換成能切分中文的,例如:r"(?<=[。?!\n])",也就是以中文的句號、問號、感嘆號以及換行符來進行切分。

SemanticChunker的實現源碼如下:

import re

def _get_single_sentences_list(self, text: str) -> List[str]:
    return re.split(self.sentence_split_regex, text)

句子 embedding

這一步是將每個句子進行 embedding,理論上接著就以每個句子 embedding 結果來計算相鄰句子的距離就可以了。但通過實際操作發現對單個句子處理噪音比較大,后續切分的效果并不理想,因此 SemanticChunker 通過 buffer_size 來控制當前句子前、后各取幾個句子組成一組來計算 embedding 并計算余弦距離。例如buffer_size設置為為1(默認值),表示取當前句子前、后各取1個句子組成一組來計算 embedding。

SemanticChunker的實現源碼如下:

首先根據buffer_size得到當前句子的組合。

def combine_sentences(sentences: List[dict], buffer_size: int = 1) -> List[dict]:
    for i inrange(len(sentences)):
        # 創建一個字符串變量來保存連接的句子
        combined_sentence = ""

        # 添加當前句子之前 buffer_size 個句子
        for j inrange(i - buffer_size, i):
            if j >= 0:
                combined_sentence += sentences[j]["sentence"] + " "

        # 添加當前句子
        combined_sentence += sentences[i]["sentence"]

        # 添加當前句子之后 buffer_size 個句子
        for j inrange(i + 1, i + 1 + buffer_size):
            if j < len(sentences):
                combined_sentence += " " + sentences[j]["sentence"]

        # 將合并好的句子存儲在當前的句子 combined_sentence 中
        sentences[i]["combined_sentence"] = combined_sentence

    return sentences

然后根據通過參數 embeddings傳入的向量模型對句子組合進行 embedding。

def _calculate_sentence_distances(self, single_sentences_list: List[str]) -> Tuple[List[float], List[dict]]:
    _sentences = [
        {"sentence": x, "index": i} for i, x in enumerate(single_sentences_list)
    ]
    sentences = combine_sentences(_sentences, self.buffer_size)
    embeddings = self.embeddings.embed_documents(
        [x["combined_sentence"] for x in sentences]
    )
    for i, sentence in enumerate(sentences):
        sentence["combined_sentence_embedding"] = embeddings[i]

    return calculate_cosine_distances(sentences)

計算相鄰句子(組)余弦距離

這一步就是通過計算相鄰句子(組) 的余弦相似度來得到相鄰句子(組) 的余弦距離。

將橫軸記為句子(組)的序號,縱軸為相鄰句子(組) 的余弦距離,就可得到下面類似的圖:

圖片

SemanticChunker的實現源碼如下:

from langchain_community.utils.math import cosine_similarity

defcalculate_cosine_distances(sentences: List[dict]) -> Tuple[List[float], List[dict]]:
    distances = []
    for i inrange(len(sentences) - 1):
        embedding_current = sentences[i]["combined_sentence_embedding"]
        embedding_next = sentences[i + 1]["combined_sentence_embedding"]

        # 計算余弦相似度
        similarity = cosine_similarity([embedding_current], [embedding_next])[0][0]

        # 轉換成余弦距離
        distance = 1 - similarity
        distances.append(distance)

        # 保存余弦距離
        sentences[i]["distance_to_next"] = distance

    # 【可選】最后一個句子的處理
    # sentences[-1]['distance_to_next'] = None  # 或其它默認值

    return distances, sentences

計算切分點

如何計算切分點,SemanticChunker給出了4種方法:

  • percentile: 分位法,默認方法。將所有余弦距離在第 X 分位數的值作為閾值,并在那些余弦距離超過該閾值的位置進行切分。第 X 分位數可通過breakpoint_threshold_amount 設置,默認為 95。還可以通過 number_of_chunks 指定切分后的文檔塊總數量,采用線性插值的方式反向推導出該分位數;

SemanticChunker的實現源碼如下:

import numpy as np

def_calculate_breakpoint_threshold(self, distances: List[float]) -> Tuple[float, List[float]]:
# 第一種方式:指定分位數
return cast(
      float,
      np.percentile(distances, self.breakpoint_threshold_amount),
  ), distances

# 第二種方式:通過 number_of_chunks 反向推導分位數
  x1, y1 = len(distances), 0.0
  x2, y2 = 1.0, 100.0
  x = max(min(self.number_of_chunks, x1), x2)
if x2 == x1:
      y = y2
else:
      y = y1 + ((y2 - y1) / (x2 - x1)) * (x - x1) # 線性插值
  y = min(max(y, 0), 100)
    return cast(
      float,
      np.percentile(distances, y),), 
      distances
  • standard_deviation: 標準差偏離法,是統計學中表示偏離的常規方法,這種方法比較適合正態分布。將所有余弦距離的平均值加上 X 倍的所有余弦距離標準差的值作為閾值,并在那些余弦距離超過該閾值的位置進行切分。X 倍可通過breakpoint_threshold_amount 設置,默認為 3,這是最常用的值;

SemanticChunker的實現源碼如下:

import numpy as np

def _calculate_breakpoint_threshold(self, distances: List[float]) -> Tuple[float, List[float]]:
  return cast(
    float,
    np.mean(distances) + 
      self.breakpoint_threshold_amount * np.std(distances),), 
    distances
  • interquartile: 四分位距法,是統計學中表示偏離的另一種常規方法,這種方法計算分位數,所以數據分布不那么正態問題也不大。將所有余弦距離的平均值加上 X 倍的所有余弦距離四分位距的值作為閾值,并在那些余弦距離超過該閾值的位置進行切分。X 倍可通過breakpoint_threshold_amount 設置,默認為 1.5,也是最常用的值;

SemanticChunker的實現源碼如下:

import numpy as np

def _calculate_breakpoint_threshold(self, distances: List[float]) -> Tuple[float, List[float]]:
  # 取出25分位(下四分位)和75分位(上四分位)的數值
  q1, q3 = np.percentile(distances, [25, 75])

  # 計算兩個分位的差值(四分位距)
  iqr = q3 - q1

  return np.mean(distances) + 
            self.breakpoint_threshold_amount * iqr, distances
  • gradient: 梯度法。首先計算所有余弦距離的變化梯度,變化梯度計算出來后,就可以知道哪個地方余弦距離變化得快,然后將所有變化梯度在第 X 分位數的值作為閾值,并在那些余弦距離超過該閾值的位置進行切分。第 X 分位數可通過breakpoint_threshold_amount 設置,默認為 95。

SemanticChunker的實現源碼如下:

import numpy as np

def _calculate_breakpoint_threshold(self, distances: List[float]) -> Tuple[float, List[float]]:
  # 計算所有余弦距離的變化梯度
  distance_gradient = np.gradient(distances, range(0, len(distances)))
  return cast(
      float,
      np.percentile(distance_gradient,
                    self.breakpoint_threshold_amount)),
      distance_gradient

按切分點切分

通過第4步各方法得到切分點后,就可以按切分點對文檔進行切分(通過設置min_chunk_size控制合并較小的塊),就可得到下面類似的圖(包括切分位置以及切片):

圖片

SemanticChunker的實現源碼如下:

def split_text(self, text: str,) -> List[str]:
      # 計算相鄰句子的余弦距離
      distances, sentences = self._calculate_sentence_distances(single_sentences_list)

      # 計算切分點
      breakpoint_distance_threshold, breakpoint_array = self._calculate_breakpoint_threshold(distances)

      indices_above_thresh = [
          i
          for i, x inenumerate(breakpoint_array)
          if x > breakpoint_distance_threshold
      ]

      chunks = []
      start_index = 0

      # 遍歷切分點來分割句子
      for index in indices_above_thresh:
          end_index = index
          group = sentences[start_index : end_index + 1]
          combined_text = " ".join([d["sentence"] for d in group])
        
          # 通過設置 min_chunk_size 來合并較小的文檔塊
          if (
              self.min_chunk_size isnotNone
              andlen(combined_text) < self.min_chunk_size
          ):
              continue
          chunks.append(combined_text)

          start_index = index + 1

      if start_index < len(sentences):
          combined_text = " ".join([d["sentence"] for d in sentences[start_index:]])
          chunks.append(combined_text)
      return chunks

代碼實踐

原 TypeScript 項目已使用 Python 進行了重構,后續將優先使用 Python 進行代碼實踐和講解。

其中:RAG.libs 中是封裝好的各種不同作用的模塊,如 RAG/libs/text_splitter.py 是封裝好的文檔切分器,RAG/libs/evaluator.py 是封裝好的評估器,因此文中不再貼具體的代碼,如需查看具體代碼實現,請移步到 github 代碼倉庫中查看。

本文完整代碼地址[2]:https://github.com/laixiangran/ai-learn-python/blob/main/RAG/examples/06_semantic_splitting.py

先看下基于句子余弦距離的語義切分的評估結果:

圖片

從評估結果來看,相較于 RecursiveCharacterTextSplitter 的切分方法,在上下文召回率、上下文相關性以及答案準確性都有不同程度的提升。

加載文件

from RAG.libs.file_loader import FileLoader

file_loader = FileLoader(
    file_path="RAG/datas/2024少兒編程教育行業發展趨勢報告.md",
    provider="customMarkdownLoader",
)
documents = file_loader.load()

語義切分

因為我們的文檔只要是中文,因此需要將 sentence_split_regex修改成可對中文切分的規則,如:r"(?<=[。?!\n])"

from langchain_experimental.text_splitter import SemanticChunker
from RAG.libs.embedding import Embedding

# 向量模型
embeddings = Embedding(model="nomic-embed-text", provider="ollama")

# 使用 SemanticChunker 切分
text_splitter = SemanticChunker(
    embeddings=embeddings,
    breakpoint_threshold_type="percentile",
    sentence_split_regex=r"(?<=[。?!\n])",
)
documents = text_splitter.split_documents(documents=documents)

切分后處理

使用SemanticChunker進行切分,會出現較短或者較長的切片。比如通過percentile進行切分后的結果可以看到,最小的文檔塊大小只有 1,最大的文檔塊大小有 3346。因此,為了更好的檢索效果,我們一般需要=對較長的文檔做二次切分、對較短的文檔進行合并和添加標題等其它切分后處理。

count 75 // 總數
mean 731 // 平均值
std 685 // 標準差
min 1 // 最小值
25% 218 // 25分位值
50% 568 // 50分位值
75% 990 // 75分位值
90% 1535 // 90分位值
97% 2577 // 97分位值
99% 2876 // 99分位值
max 3346 // 最大值

將較大的文檔塊進行二次切分、合并較小的塊和添加標題:

from RAG.libs.text_splitter import (
    TextSplitter,
    merge_small_documents,
    add_headers_to_documents,
)

# 將較大的文檔塊進行二次切分
text_splitter = TextSplitter(
    provider="recursiveCharacter",
    chunk_size=500,
    chunk_overlap=0,
)
documents = text_splitter.split_documents(documents)

# 合并較小的塊和添加標題
documents = merge_small_documents(documents, merge_max_length=100)
documents = add_headers_to_documents(documents)

效果評估

from RAG.libs.evaluator import BatchEvaluator

eval_result = BatchEvaluator(
    chat_model=chat_model,
    vector_store=vector_store,
    qa_data=qa_data,
    top_k=3,
    filter=filter,
    output_path=output_path,
)

結語

本文介紹了一種更智能的切分方法 - 基于句子余弦距離的語義切分,并通過 langchain-experimental 中的 SemanticChunker 的源碼來帶大家了解了語義切分的實現原理。

從最后評估結果來看,相較于 RecursiveCharacterTextSplitter 的切分方法,在上下文召回率、上下文相關性以及答案準確性都有不同程度的提升,這說明通過基于句子余弦距離的語義切分方法對文檔切分優化具有一定的可行性,大家可以根據自己的實際情況進一步驗證,歡迎大家留言交流。

引用鏈接

[1] SemanticChunker: https://github.com/langchain-ai/langchain-experimental/blob/main/libs/experimental/langchain_experimental/text_splitter.py#L99

[2] 本文完整代碼地址: https://github.com/laixiangran/ai-learn-python/blob/main/RAG/examples/06_semantic_splitting.py

責任編輯:龐桂玉 來源: 燃哥講AI
相關推薦

2025-06-10 04:30:00

2024-09-04 09:11:42

2025-08-01 01:55:00

2022-01-07 14:00:35

分庫分表業務量

2019-11-25 10:12:59

Python技巧工具

2011-08-18 16:03:48

數據切分MySQL

2025-04-02 04:00:00

RAG分塊優化

2025-05-22 06:48:50

RAGAI應用開發框架DeepSeek

2017-07-17 14:45:43

數據庫DB分庫切分策略

2024-09-29 00:00:02

2017-12-08 10:42:49

HBase切分細節

2017-08-28 16:40:07

Region切分觸發策略

2021-03-17 16:15:55

數據MySQL 架構

2024-06-24 14:32:33

2025-10-30 02:11:00

2017-06-19 16:45:41

數據庫水平切分用戶中心

2025-05-26 09:57:46

2024-02-05 14:12:37

大模型RAG架構

2023-10-10 14:03:47

swap排序解法

2025-05-07 08:35:11

點贊
收藏

51CTO技術棧公眾號

国产a级一级片| 欧美另类视频在线| 国模无码国产精品视频| 哺乳挤奶一区二区三区免费看| 一区二区三区影院| 欧美精品国产精品久久久| 一卡二卡三卡在线观看| 亚洲激情视频| 日韩在线观看免费全集电视剧网站 | 成人激情电影在线| 日韩精品一区在线观看| 久久久久久久少妇| 丁香花电影在线观看完整版| 国产丝袜欧美中文另类| 97神马电影| 这里只有精品国产| 国产精品一卡| 久久91亚洲精品中文字幕奶水| 国产人妻大战黑人20p| 日本精品一区二区三区在线观看视频| 色婷婷激情综合| 日本中文字幕在线视频观看| 91欧美在线视频| 久久综合久久99| 成人自拍爱视频| 91丨九色丨蝌蚪丨对白| 日韩精品三区四区| 91精品国产99| 国产乡下妇女做爰| 欧美一区二区三区免费看| 亚洲系列中文字幕| 亚洲做受高潮无遮挡| 亚洲一区 二区| 91精品午夜视频| 欧美午夜aaaaaa免费视频| 亚洲啊v在线| 亚洲国产精品天堂| 黄色特一级视频| 国产在线观看91| 中文字幕第一区二区| 蜜桃导航-精品导航| 婷婷开心激情网| 成人aa视频在线观看| 99久久免费国| 国产 日韩 欧美 综合| 国产精品自在在线| 91手机在线视频| 99久久精品日本一区二区免费| 久久爱www久久做| 国产精品久久久久久久久久久久| 无码aⅴ精品一区二区三区| 国产精品久久777777毛茸茸| 91精品国产高清| 五月天激情国产综合婷婷婷| 鲁大师成人一区二区三区| 2018日韩中文字幕| 狠狠人妻久久久久久| 另类天堂av| 亚洲免费成人网| 久久免费视频66| 亚洲成人av在线播放| 俄罗斯女人裸体性做爰| 蜜桃精品一区二区三区| 欧美一区二区高清| 日本一区二区三区在线免费观看| 婷婷久久免费视频| 日韩一区二区中文字幕| 亚洲av无码久久精品色欲| 视频一区日韩精品| 亚洲成av人乱码色午夜| 国产成人精品一区二区三区在线观看 | 天天干天天爽天天操| 99久久99久久综合| 欧美专区一二三| 日本美女在线中文版| 一区二区三区四区中文字幕| 99在线免费视频观看| www.成人爱| 欧美精三区欧美精三区| 中文字幕永久免费| 欧美人妖在线| 久久久精品一区二区三区| 欧美日韩一级在线观看| 亚洲国产片色| 国产精品美腿一区在线看| 国产美女免费视频| 99亚偷拍自图区亚洲| 视频一区国产精品| 调教一区二区| 日本二三区不卡| 奇米777在线视频| 丝袜美腿综合| 久久视频在线视频| 成人精品免费在线观看| 激情都市一区二区| 久久久久久国产精品mv| 欧美videos极品另类| 亚洲成人免费观看| 性生活免费在线观看| 国产成人精品福利| 最近2019免费中文字幕视频三| 久久97人妻无码一区二区三区| 久久天堂精品| 肥熟一91porny丨九色丨| 男人的天堂在线| 夜夜亚洲天天久久| 一区二区三区韩国| 久久久久观看| 欧美成人中文字幕在线| 一级特黄免费视频| hitomi一区二区三区精品| 亚洲一区精彩视频| 欧美大胆成人| 亚洲成人中文字幕| 免费成人深夜蜜桃视频| 亚洲影音先锋| 国产高清在线精品一区二区三区| 五月婷婷在线视频| 欧美性xxxxx极品娇小| 中文字幕在线观看视频www| 日韩一区亚洲二区| 热久久这里只有精品| 国产综合视频在线| 亚洲狠狠丁香婷婷综合久久久| 亚洲成人av免费看| 午夜精品影视国产一区在线麻豆| 欧美激情精品久久久| 国产精品无码在线播放| 国产精品欧美经典| 男人的天堂日韩| 一区二区导航| 国产91精品不卡视频| 手机av免费在线观看| 亚洲综合色噜噜狠狠| 久久精品无码一区二区三区毛片| 97欧美在线视频| 国产精品入口尤物| 成人亚洲性情网站www在线观看| 欧美日韩在线免费| 国产伦精品一区二区免费| 欧美天天视频| 懂色中文一区二区三区在线视频| 伊人春色在线观看| 日韩欧美123| 中文字幕在线观看成人| 国产乱人伦偷精品视频免下载 | 国产精品无码电影| 亚洲另类黄色| 精品一区国产| gay欧美网站| 国产午夜精品久久久| 五月天婷婷久久| 久久理论电影网| 日韩一级免费在线观看| 俺要去色综合狠狠| 国产精品一区二区三区久久| 秋霞午夜在线观看| 制服丝袜激情欧洲亚洲| 日韩女优一区二区| 成人v精品蜜桃久久一区| 久久久久久久久久久99| 国产99精品一区| 国产精品欧美日韩久久| 日韩免费网站| 日韩视频一区在线观看| 久草中文在线视频| 91在线精品一区二区| 欧美牲交a欧美牲交aⅴ免费真 | 亚洲自拍一区在线观看| 国产精品青草综合久久久久99| 最新免费av网址| 国产在线不卡| 欧美理论一区二区| 亚洲精品66| 欧美精品久久久久久久免费观看| 三级小视频在线观看| 色婷婷av一区二区三区之一色屋| 国产传媒视频在线| 国产成人精品一区二区三区网站观看| 欧美 日本 亚洲| 欧美aaaa视频| 国产伦精品一区二区三区免| 欧美艳星kaydenkross| 日韩在线视频网| 国产av一区二区三区| 欧美日韩国产中文字幕 | 91成人精品视频| 国产精品香蕉视屏| 精品国产欧美日韩一区二区三区| 欧美精品免费在线| 免费一级在线观看| 日韩一级黄色片| 五月婷婷激情视频| 亚洲精品国产视频| 91激情视频在线观看| 国产成人一区在线| 熟女人妇 成熟妇女系列视频| 99久久婷婷国产综合精品电影√| 国产亚洲第一区| 亚洲精品第一| 日本午夜在线亚洲.国产| 韩国av网站在线| 亚洲欧洲在线观看| 亚洲精品一区二区三区新线路| 日本黄色一区二区| 国产一卡二卡在线播放| 国产精品久久久久一区 | 色爱综合av| 91网站免费观看| 亚洲精品一级二级| 欧美激情免费视频| 毛片网站在线免费观看| 亚洲欧洲av一区二区| 亚洲av无码国产精品久久不卡| 在线观看成人小视频| 亚洲国产综合久久| 亚洲男人的天堂在线aⅴ视频| 男人操女人动态图| 99久久亚洲一区二区三区青草| 亚洲欧美天堂在线| 麻豆国产精品一区二区三区| 国产性xxxx18免费观看视频| 国内综合精品午夜久久资源| 二级片在线观看| 日韩午夜电影网| 午夜欧美性电影| 精品国产一区二区三区小蝌蚪 | 欧美日韩理论片| 秋霞国产午夜精品免费视频| 日韩欧美xxxx| 久久精品一区| av免费播放网址| 久久大逼视频| 国产真实乱子伦| 亚洲女同在线| 国产最新免费视频| 99精品免费视频| 激情伊人五月天| 99视频一区| 日韩在线一级片| 亚洲女同在线| 国产精品wwwww| 日日嗨av一区二区三区四区| 激情综合网婷婷| 爽爽淫人综合网网站| 少妇性l交大片| 日产欧产美韩系列久久99| 激情内射人妻1区2区3区| 亚洲激情综合| 男人天堂999| 日韩高清不卡在线| 丰满少妇在线观看| 久久激情五月婷婷| 亚洲成人手机在线观看| 国产麻豆精品95视频| 国模无码视频一区| 97久久超碰国产精品| 亚洲做受高潮无遮挡| 国产精品网站在线观看| 日本黄色录像视频| 一区二区久久久| 日韩欧美亚洲视频| 日本韩国一区二区| 在线观看免费观看在线| 日韩一区二区在线播放| 黄色一级大片在线免费看国产一| 亚洲精品国产综合久久| 国产女主播在线直播| 精品国产区一区二区三区在线观看| 日韩黄色影院| 欧美国产日本高清在线 | 激情成人综合| 欧美韩国日本在线| 精品一区二区三区在线观看| 欧美图片自拍偷拍| 久久亚洲精华国产精华液| 人妻互换一区二区激情偷拍| 洋洋av久久久久久久一区| 国产91精品一区| 在线成人午夜影院| 性感美女视频一二三| 中文字幕亚洲综合| 操喷在线视频| 国产精品亚洲аv天堂网| 亚洲经典视频| 日本一区视频在线观看| 中文字幕日韩欧美精品高清在线| www.中文字幕在线| 久久国产成人午夜av影院| 国产不卡一二三| 欧美国产视频在线| 精品无码人妻一区二区三| 在线免费观看不卡av| www国产一区| 中文字幕亚洲第一| av中文字幕在线观看第一页| 国产精品久在线观看| 狼人天天伊人久久| 中文字幕一区二区三区有限公司| 在线亚洲精品| 香蕉视频xxx| 国产精品天干天干在线综合| 日本五十路女优| 欧美一区国产二区| 国产精品视频二区三区| 久久久久久久av| avtt久久| 亚洲国产精品一区二区第四页av| 在线播放日韩| 五月天六月丁香| 国产精品无码永久免费888| 青草视频在线观看免费| 日韩欧美国产系列| 免费黄网在线观看| 国产精品久久久久久久久久久久久久| ccyy激情综合| 男女h黄动漫啪啪无遮挡软件| 日韩av成人高清| 草草影院第一页| 欧美日韩国产一中文字不卡| 午夜精品久久久久久久99热黄桃| 日韩亚洲在线观看| 日韩一级二级| 欧美在线激情| 午夜综合激情| 中文字幕 亚洲一区| 一区二区三区精品| 99久久精品国产色欲| 另类少妇人与禽zozz0性伦| 激情久久一区二区| 午夜精品一区二区三区四区 | 成人欧美在线观看| 日韩电影一区| 欧美婷婷精品激情| 日本一区二区三区在线观看| 国产99免费视频| 亚洲美女黄色片| 深夜成人福利| 欧美一区二区在线视频观看| 免费在线成人| 在线不卡av电影| 日本精品视频一区二区三区| 国产免费a∨片在线观看不卡| 欧洲一区二区视频| 国产99精品一区| 欧美日韩在线观看不卡| 亚洲国产成人午夜在线一区| 自拍偷拍福利视频| 最近2019中文字幕第三页视频| 亚洲网站免费| 免费看av软件| 国产精品91xxx| 精品无码m3u8在线观看| 亚洲成人久久一区| 欧美黑人巨大xxxxx| 日韩精品久久久| 久久99精品一区二区三区| 综合五月激情网| 精品三级在线看| 欧美一级鲁丝片| 欧洲精品久久| 韩国精品一区二区| 久久免费黄色网址| 日韩精品免费电影| 日韩性xxx| 欧美xxxx吸乳| hitomi一区二区三区精品| 日本一区二区免费电影| 中文字幕日韩综合av| 日韩激情欧美| 成人在线免费在线观看| 国产欧美日韩综合精品一区二区| 国产尤物在线观看| 久久久久久久国产精品视频| 伊人久久大香线蕉无限次| 日本中文字幕影院| 亚洲国产一区视频| 高清国产福利在线观看| 成人激情视频网| 国产精品久久777777毛茸茸| 成人午夜免费影院| 欧美成人vps| 欧美va在线观看| 亚洲黄色网址在线观看| 久久在线观看免费| 国产精品国产精品国产专区| 午夜精品久久久久久久男人的天堂 | 国产美女一区视频| 日韩欧美一区二区三区四区五区| 国产自产2019最新不卡| 羞羞影院体验区| 蜜臀久久99精品久久久久久宅男 | 一本色道久久99精品综合| 国产成人丝袜美腿| 日韩电影在线观看一区二区| 精品少妇v888av| 欧美日韩在线二区| 欧美在线一级片| 538prom精品视频线放| 成人美女大片|