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

基于Llama3,為本地文件創建生成式AI搜索引擎 精華

發布于 2024-8-2 15:22
瀏覽
0收藏

本文分享一個開源項目——一款創新的生成式搜索引擎,能夠實現用戶與本地文件的智能互動。此項目在微軟Copilot等現有工具的基礎上,推出了一種開放源代碼的替代方案,旨在推動技術共享與創新。

1 系統設計

為構建本地生成式搜索引擎或助手,需要幾個組件:

  • 內容索引系統:負責存儲本地文件內容,并配備信息檢索引擎,以便高效地搜索與用戶查詢或問題最相關的文檔。
  • 語言模型:用于分析選定的本地文檔內容,并據此生成精煉的總結性答案。
  • 用戶界面:為用戶提供直觀的操作界面,以便輕松地進行查詢和獲取信息。

組件之間的交互方式如下所示:

基于Llama3,為本地文件創建生成式AI搜索引擎-AI.x社區

系統設計和架構。使用Qdrant作為向量存儲,Streamlit用于用戶界面。Llama 3可以通過Nvidia NIM API(700B版本)使用,也可以通過HuggingFace下載(80B版本)。文檔分塊使用Langchain完成。

構建本地生成式搜索引擎的第一步是創建索引,用以存儲和檢索本地文件內容。當用戶提出問題,系統會通過這個索引快速定位到最相關的文檔。隨后,選定的文檔內容被送入高級語言模型,該模型不僅生成答案,還提供對引用文檔的明確標注。最終,用戶界面將這些信息以清晰、易于理解的方式展示給用戶。

2 語義索引

語義索引旨在通過分析文件內容與查詢之間的相似度,提供最相關的文檔匹配。索引的構建采用了Qdrant作為其向量存儲解決方案。Qdrant客戶端庫的便利之處在于,它不需要完整的服務器端安裝,便能在工作內存中直接進行文檔相似性比較,極大地簡化了部署流程,僅需通過pip命令安裝Qdrant客戶端即可。

Qdrant初始化時,需要預先設定所使用的向量化方法和度量標準(注意,hf參數稍后定義)。向量化和度量的具體配置應在客戶端初始化階段完成。以下是Qdrant初始化的一個示例:

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams
client = QdrantClient(path="qdrant/")
collection_name = "MyCollection"
if client.collection_exists(collection_name):
    client.delete_collection(collection_name)

client.create_collection(collection_name,vectors_cnotallow=VectorParams(size=768, distance=Distance.DOT))
qdrant = Qdrant(client, collection_name, hf)

為構建向量索引,必須對硬盤中的文檔進行嵌入處理。需要選擇合適的嵌入方法和向量比較度量標準,不同的段落、句子或詞嵌入技術將產生不同的結果。在文檔向量搜索中,主要挑戰之一是非對稱搜索問題,這在信息檢索領域極為常見,尤其是在處理短查詢與長文檔匹配時。傳統的單詞或句子嵌入技術通常針對相似長度的文檔進行優化,如果文檔長度與查詢長度差異過大,就可能導致信息檢索效果不佳。

然而,有一種嵌入方法能夠有效應對非對稱搜索問題。以MSMARCO數據集為例,該數據集基于Bing的搜索查詢和文檔,由Microsoft發布,并針對此類問題進行了優化。MSMARCO數據集的模型經過微調,能夠提供出色的搜索效果,非常適合解決當前面臨的問題。

在本次實現中,選用了針對MSMARCO數據集進行過微調的模型,名為:

sentence-transformers/msmarco-bert-base-dot-v5

這個模型基于BERT架構,并針對點積相似性度量進行了特別優化。在初始化Qdrant客戶端時,已明確采用點積作為衡量相似性的方法(注意此模型的維度為768):

client.create_collection(collection_name,vectors_cnotallow=VectorParams(size=768, distance=Distance.DOT))

在選擇相似性度量標準時,雖然余弦相似性是一個可行選擇,但鑒于模型已針對點積優化,采用點積能夠實現更優的性能表現。點積的優勢在于它不僅關注向量間的角度差異,還包括了向量的大小因素,這在評估向量整體相似度時尤為重要。通過歸一化處理,可以在特定條件下使兩種度量標準達到相同效果。然而,當向量的大小成為一個關鍵考量時,點積顯然是更為合適的度量手段。

模型初始化建議利用GPU以提升計算效率,具體代碼實現如下:

model_name = "sentence-transformers/msmarco-bert-base-dot-v5"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': True}
hf = HuggingFaceEmbeddings(
    model_name=model_name,
    model_kwargs=model_kwargs,
    encode_kwargs=encode_kwargs
)

BERT類模型受限于其內存消耗的二次方增長特性,只能處理有限長度的上下文,通常不超過512個token。面對這一局限,有兩種應對策略:一是僅利用文檔前512個token生成答案,舍棄之后的內容;二是將文檔切分為多個小塊,每塊作為一個獨立單元存儲于索引之中。為了保留完整的信息,我們選擇了后者。文檔的分塊工作,計劃利用LangChain的內置分塊工具來完成:

from langchain_text_splitters import TokenTextSplitter
text_splitter = TokenTextSplitter(chunk_size=500, chunk_overlap=50)
texts = text_splitter.split_text(file_content)
metadata = []
for i in range(0,len(texts)):
    metadata.append({"path":file})
qdrant.add_texts(texts,metadatas=metadata)

在編寫的代碼中,把文本切割成500個token的段落,并設置了50個token的重疊區域,這樣做是為了在段落的首尾保持上下文的連貫性。接著,為每個段落創建了包含文檔存儲路徑的元數據,并將其與文本段落一并索引。

在將文件內容索引之前,必須先讀取這些文件。而在讀取之前,需要先確定哪些文件需要被索引。本項目簡化了這一流程,允許用戶指定他們希望索引的文件夾。索引器將遞歸地搜索該文件夾及其子文件夾中的所有文件,并索引那些支持的文件類型,如PDF、Word、PPT和TXT格式。

以下是檢索給定文件夾及其子文件夾內所有文件的遞歸方法:

def get_files(dir):
    file_list = []
    for f in listdir(dir):
        if isfile(join(dir,f)):
            file_list.append(join(dir,f))
        elif isdir(join(dir,f)):
            file_list= file_list + get_files(join(dir,f))
    return file_list

完成文件檢索后,接下來便是讀取這些文件中的文本內容。目前,工具支持的文件格式包括MS Word文檔(.docx)、PDF文檔、MS PowerPoint演示文稿(.pptx)以及純文本文件(.txt)。

對于MS Word文檔的讀取,采用docx-python庫來實現。以下是將文檔內容讀取到字符串變量中的函數示例:

import docx
def getTextFromWord(filename):
    doc = docx.Document(filename)
    fullText = []
    for para in doc.paragraphs:
        fullText.append(para.text)
    return '\n'.join(fullText)

對于MS PowerPoint文件的處理,采取相似的方法。為此,需要下載并安裝pptx-python庫,并編寫如下函數:

from pptx import Presentation
def getTextFromPPTX(filename):
    prs = Presentation(filename)
    fullText = []
    for slide in prs.slides:
        for shape in slide.shapes:
            fullText.append(shape.text)
    return '\n'.join(fullText)

讀取文本文件:

f = open(file,'r')
file_content = f.read()
f.close()

對于PDF文件,使用 PyPDF2 庫:

reader = PyPDF2.PdfReader(file)
for i in range(0,len(reader.pages)):
    file_content = file_content + " "+reader.pages[i].extract_text()

最后,整個索引函數是這樣:

file_content = ""
    for file in onlyfiles:
        file_content = ""
        if file.endswith(".pdf"):
            print("indexing "+file)
            reader = PyPDF2.PdfReader(file)
            for i in range(0,len(reader.pages)):
                file_content = file_content + " "+reader.pages[i].extract_text()
        elif file.endswith(".txt"):
            print("indexing " + file)
            f = open(file,'r')
            file_content = f.read()
            f.close()
        elif file.endswith(".docx"):
            print("indexing " + file)
            file_content = getTextFromWord(file)
        elif file.endswith(".pptx"):
            print("indexing " + file)
            file_content = getTextFromPPTX(file)
        else:
            continue
        text_splitter = TokenTextSplitter(chunk_size=500, chunk_overlap=50)
        texts = text_splitter.split_text(file_content)
        metadata = []
        for i in range(0,len(texts)):
            metadata.append({"path":file})
        qdrant.add_texts(texts,metadatas=metadata)
    print(onlyfiles)
    print("Finished indexing!")

如前所述,這里采用了LangChain的TokenTextSplitter工具,將文本劃分為500個token的段落,并在段落間保留了50個token的重疊,確保了內容的連續性。在此基礎上,已經成功建立了索引。接下來,將開發一個Web服務,它不僅能夠查詢索引,還能根據查詢結果智能生成答案。

3 生成式搜索API

這里通過FastAPI框架搭建Web服務,用于承載生成式搜索引擎。這個API將連接到之前建立的Qdrant客戶端索引,通過向量相似性搜索算法深入挖掘,再借助Llama 3模型對篩選出的最相關塊生成精準答案,并將這些答案反饋給用戶。

為了配置并引入生成式搜索的關鍵組件,以下是相應的代碼示例:

from fastapi import FastAPI
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_qdrant import Qdrant
from qdrant_client import QdrantClient
from pydantic import BaseModel
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
import environment_var
import os
from openai import OpenAI

class Item(BaseModel):
    query: str
    def __init__(self, query: str) -> None:
        super().__init__(query=query)

FastAPI 框架用來創建 API 接口,以實現數據的高效交互。通過 qdrant_client 庫,能夠訪問之前建立的索引數據,而 langchain_qdrant 庫則增強了其功能。在處理模型嵌入和本地化部署 Llama 3 模型時,分別采用了 PyTorch 和 Transformers 這兩個業界領先的庫。此外,項目還通過 OpenAI 庫與 NVIDIA NIM API 進行了集成,相關的 API 密鑰被安全地存儲在預設的 environment_var 文件中,確保了與 Nvidia 和 HuggingFace 的無縫對接。

為了更高效地處理請求參數,開發了一個名為 Item 的類,它基于 Pydantic 的 BaseModel 進行擴展,并且包含了一個關鍵字段:query,該字段專用于捕獲和傳遞用戶的查詢指令。

緊接著,項目將啟動機器學習模型的初始化過程:

model_name = "sentence-transformers/msmarco-bert-base-dot-v5"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': True}
hf = HuggingFaceEmbeddings(
    model_name=model_name,
    model_kwargs=model_kwargs,
    encode_kwargs=encode_kwargs
)

os.environ["HF_TOKEN"] = environment_var.hf_token
use_nvidia_api = False
use_quantized = True
if environment_var.nvidia_key !="":
    client_ai = OpenAI(
        base_url="https://integrate.api.nvidia.com/v1",
        api_key=environment_var.nvidia_key
    )
    use_nvidia_api = True
elif use_quantized:
    model_id = "Kameshr/LLAMA-3-Quantized"
    tokenizer = AutoTokenizer.from_pretrained(model_id)
    model = AutoModelForCausalLM.from_pretrained(
        model_id,
        torch_dtype=torch.float16,
        device_map="auto",
    )
else:
    model_id = "meta-llama/Meta-Llama-3-8B-Instruct"
    tokenizer = AutoTokenizer.from_pretrained(model_id)
    model = AutoModelForCausalLM.from_pretrained(
        model_id,
        torch_dtype=torch.float16,
        device_map="auto",
    )

系統已完成對基于MSMARCO數據集優化的BERT模型的加載,該模型用于文檔索引工作。

若存在nvidia_key,系統會調用NVIDIA NIM API,啟用具有70億參數的Llama 3 instruct模型。若無nvidia_key,鑒于本地部署限制,將加載或量化處理后的8億參數Llama 3模型,使其在減少內存占用的同時,保持模型性能。

接下來,啟動Qdrant客戶端的初始化過程,以便進行高效的數據索引和檢索:

client = QdrantClient(path="qdrant/")
collection_name = "MyCollection"
qdrant = Qdrant(client, collection_name, hf)

同時,使用 FastAPI 創建第一個模擬 GET 函數:

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

這個函數會返回格式為 {"message":"Hello World"} 的 JSON。

為了確保API能夠正常工作,將設計兩個功能:第一個功能專門進行語義搜索;第二個功能則在搜索的基礎上,選取最相關的前10個文本塊作為上下文,進一步生成答案,并對使用的文檔進行引用。

@app.post("/search")
def search(Item:Item):
    query = Item.query
    search_result = qdrant.similarity_search(
        query=query, k=10
    )
    i = 0
    list_res = []
    for res in search_result:
        list_res.append({"id":i,"path":res.metadata.get("path"),"content":res.page_content})
    return list_res

@app.post("/ask_localai")
async def ask_localai(Item:Item):
    query = Item.query
    search_result = qdrant.similarity_search(
        query=query, k=10
    )
    i = 0
    list_res = []
    context = ""
    mappings = {}
    i = 0
    for res in search_result:
        context = context + str(i)+"\n"+res.page_content+"\n\n"
        mappings[i] = res.metadata.get("path")
        list_res.append({"id":i,"path":res.metadata.get("path"),"content":res.page_content})
        i = i +1

    rolemsg = {"role": "system",
               "content": "Answer user's question using documents given in the context. In the context are documents that should contain an answer. Please always reference document id (in squere brackets, for example [0],[1]) of the document that was used to make a claim. Use as many citations and documents as it is necessary to answer question."}
    messages = [
        rolemsg,
        {"role": "user", "content": "Documents:\n"+context+"\n\nQuestion: "+query},
    ]
    if use_nvidia_api:
        completion = client_ai.chat.completions.create(
            model="meta/llama3-70b-instruct",
            messages=messages,
            temperature=0.5,
            top_p=1,
            max_tokens=1024,
            stream=False
        )
        response = completion.choices[0].message.content
    else:
        input_ids = tokenizer.apply_chat_template(
                messages,
                add_generation_prompt=True,
                return_tensors="pt"
            ).to(model.device)


        terminators = [
            tokenizer.eos_token_id,
            tokenizer.convert_tokens_to_ids("<|eot_id|>")
            ]

        outputs = model.generate(
            input_ids,
            max_new_tokens=256,
            eos_token_id=terminators,
            do_sample=True,
            temperature=0.2,
            top_p=0.9,
        )
        response = tokenizer.decode(outputs[0][input_ids.shape[-1]:])
    return {"context":list_res,"answer":response}

這兩個函數均采用POST方法,并通過JSON格式利用Item類傳遞查詢參數。第一個函數負責返回10個最相似的文檔片段,同時提供每個片段的路徑,并賦予其從0至9的文檔ID。該函數主要執行基礎的語義搜索,使用點積作為相似性度量標準,這一點在Qdrant索引創建期間已設定——即在定義中包含了distance=Distance.DOT的參數。

第二個名為ask_localai的函數則更為復雜,它在第一個函數的搜索機制基礎上進行了擴展,增加了生成答案的功能。該函數為Llama 3模型構建了一個包含系統提示消息的提示模板,指示模型如何生成答案:

請使用上下文中給出的文檔回答用戶的提問。上下文中的文檔應當包含問題的答案。在陳述時,請始終引用用來提出主張的文檔的ID(用方括號表示,例如[0]、[1])。根據回答問題的需要,盡可能多地引用文獻和文檔。

用戶的消息包含了一個文檔列表,列表中的每個文檔都按ID(0-9)編號,并在下一行顯示文檔內容。為了保持ID與文檔路徑之間的映射關系,我們創建了一個名為list_res的列表,其中包含了ID、路徑和內容。用戶提示以“Question”一詞結束,隨后是用戶的查詢內容。

響應包含上下文和生成的答案。然而,答案再次由 Llama 3 70B 模型(使用 NVIDIA NIM API)、本地 Llama 3 8B 或本地量化的 Llama 3 8B 生成,具體取決于傳遞的參數。

API 可以從包含以下代碼的單獨文件啟動(假設生成組件在名為 api.py 的文件中,Uvicorn 的第一個參數對應文件名):

import uvicorn


if __name__=="__main__":
    uvicorn.run("api:app",host='0.0.0.0', port=8000, reload=False,  workers=3)

4 簡單的用戶界面

本地生成式搜索引擎的用戶界面是其最后一塊拼圖,采用Streamlit構建,界面簡潔,包含查詢輸入框、搜索按鈕、結果展示區以及可交互的文檔列表。關鍵代碼不足45行:

import re
import streamlit as st
import requests
import json
st.title('_:blue[Local GenAI Search]_ :sunglasses:')
question = st.text_input("Ask a question based on your local files", "")
if st.button("Ask a question"):
    st.write("The current question is \"", question+"\"")
    url = "http://127.0.0.1:8000/ask_localai"

    payload = json.dumps({
      "query": question
    })
    headers = {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    }

    response = requests.request("POST", url, headers=headers, data=payload)

    answer = json.loads(response.text)["answer"]
    rege = re.compile("\[Document\ [0-9]+\]|\[[0-9]+\]")
    m = rege.findall(answer)
    num = []
    for n in m:
        num = num + [int(s) for s in re.findall(r'\b\d+\b', n)]


    st.markdown(answer)
    documents = json.loads(response.text)['context']
    show_docs = []
    for n in num:
        for doc in documents:
            if int(doc['id']) == n:
                show_docs.append(doc)
    a = 1244
    for doc in show_docs:
        with st.expander(str(doc['id'])+" - "+doc['path']):
            st.write(doc['content'])
            with open(doc['path'], 'rb') as f:
                st.download_button("Downlaod file", f, file_name=doc['path'].split('/')[-1],key=a
                )
                a = a + 1

最終:

基于Llama3,為本地文件創建生成式AI搜索引擎-AI.x社區

5 結語

本文闡述了如何融合Qdrant的語義搜索技術與生成式人工智能,構建了針對本地文件的檢索增強生成(RAG)流程,這一流程能夠對文檔中的聲明進行引用說明。代碼總計約300行,用戶可選擇三種不同參數規模的Llama 3模型以滿足不同場景的需求。在本用例中,無論是8億還是70億參數的模型,均能穩定運行并提供出色的性能。

本文轉載自 ??AI科技論談??,作者: AI科技論談

已于2024-8-2 15:23:18修改
收藏
回復
舉報
回復
相關推薦
国产一区二区中文字幕免费看| 日韩天堂在线观看| 秋霞在线观看一区二区三区| а中文在线天堂| 欧美91大片| 欧美日本一区二区三区| 日韩欧美亚洲在线| 99热这里只有精品9| 国产欧美精品| 久久精品亚洲国产| 成人网站免费观看| 精品国产一区二区三区性色av | 精品日本一区二区三区| 中日韩av在线| 国产一区二区三区的电影 | 欧美日韩在线观看成人| 国产精品亚洲欧美日韩一区在线| 亚洲国产精品成人久久综合一区| 日本午夜在线亚洲.国产| 秋霞欧美一区二区三区视频免费| 精品国产影院| 欧美一级理论性理论a| 成人在线观看a| 国产精品一品| 国产精品乱码久久久久久| 国产精品视频自在线| 最新日韩免费视频| 亚洲妇女av| 亚洲成人久久久久| 人妻巨大乳一二三区| 青青草原av在线| 国产精品每日更新在线播放网址| 精品视频第一区| 亚洲欧美激情另类| 国产激情视频一区二区三区欧美| 国产女同一区二区| 久草免费新视频| 97精品视频在线看| 精品第一国产综合精品aⅴ| 男人日女人视频网站| 在线中文字幕视频观看| 成人免费在线视频| 久草精品电影| 隣の若妻さん波多野结衣| 国精品**一区二区三区在线蜜桃| 国产精品免费小视频| 亚洲免费在线视频观看| 亚洲一区二区三区免费在线观看| 亚洲最新av网址| 丰满圆润老女人hd| 国产一区二区三区| 欧美卡1卡2卡| 亚洲精品永久视频| 国内精彩免费自拍视频在线观看网址| 久久九九影视网| 免费h精品视频在线播放| 污污网站在线免费观看| 国内精品免费**视频| 成人a在线视频| 国产精品久久久久精| 一本久道久久久| 91精品国产91久久久| www欧美com| 欧美日韩精品| 在线观看不卡av| 国产精品久久久久久在线观看| 校园春色亚洲色图| 欧美亚洲一区二区在线| 欧美美女一级片| 精品视频在线观看免费观看 | 最好看的中文字幕| 波多野结衣欧美| 精品国产一区二区三区忘忧草| 亚洲av成人精品一区二区三区| 日韩精品第二页| 91精品国产高清一区二区三区 | 国产精品美女久久久久aⅴ国产馆| 日韩中文一区| 老司机99精品99| 国产日韩av一区二区| 国产精品一国产精品最新章节| 日韩一级片免费| 国产成人精品三级| 日韩美女主播视频| 一级黄色免费看| 成人免费福利片| 97久久夜色精品国产九色 | a级精品国产片在线观看| 久久精品第九区免费观看 | 成人1区2区3区| 91在线播放网址| 亚洲一区二区四区| jizz一区二区三区| 亚洲综合免费观看高清完整版| 在线视频精品一区| 一区二区高清不卡| 欧美激情一二三区| 亚洲人成网站在线播放2019| 污视频网站在线免费| 欧洲在线/亚洲| 中文字幕第六页| 国产区精品区| 欧美极品第一页| 中文字幕乱码在线观看| 日韩va亚洲va欧美va久久| 亚洲一区二区久久久久久| 国产乱人乱偷精品视频a人人澡| 蜜臀av一区二区三区| 国产日韩二区| 毛片在线播放网站| 亚洲综合激情另类小说区| 国产区二区三区| 日日夜夜亚洲精品| 亚洲视频视频在线| 国产一级aa大片毛片| 亚洲激情精品| 日韩av黄色在线观看| 成人福利小视频| 成人av在线电影| 中文字幕一区二区三区在线乱码| 国产一区久久精品| 亚洲香蕉伊在人在线观| 色播五月激情五月| 538任你躁精品视频网免费| 日韩在线免费视频| 无码人妻精品一区二区三区不卡| 秋霞影院一区二区| 欧美精品一区二区三区四区五区| 超碰国产在线观看| 一本大道久久a久久综合婷婷| 亚洲欧洲日韩综合| 亚洲福利天堂| 国产69精品久久久久久| 全国男人的天堂网| 一区二区三区小说| 蜜臀av午夜一区二区三区| 国内露脸中年夫妇交换精品| 欧美成人精品激情在线观看| 91尤物国产福利在线观看| 亚洲国产激情av| 成人免费xxxxx在线视频| 亚洲精品乱码日韩| 色yeye香蕉凹凸一区二区av| 中文天堂在线播放| 成人综合婷婷国产精品久久蜜臀| 免费看成人片| 91蜜桃在线视频| 91精品欧美福利在线观看| 久久久久无码国产精品一区李宗瑞 | 小嫩苞一区二区三区| 青青草成人在线观看| 成人在线免费网站| 91在线视频免费看| 亚洲国产视频在线| mm1313亚洲国产精品无码试看| 婷婷成人综合| 欧美国产日韩xxxxx| www.日日夜夜| 国产精品国产三级国产普通话三级 | 国产乱淫av一区二区三区| 久久99国产精品99久久| 黄色在线免费看| 欧美一二三区在线| 纪美影视在线观看电视版使用方法| 视频在线观看国产精品| 日韩欧美视频一区二区三区四区 | 97免费高清电视剧观看| 国产成人天天5g影院在线观看| 欧美丝袜丝交足nylons| 在线精品一区二区三区| 乱码第一页成人| 亚洲不卡1区| 精品福利在线| 欧美疯狂做受xxxx高潮| 日本电影一区二区在线观看| 亚洲综合精品久久| 欧美xxxxxbbbbb| 日韩电影免费网站| 91精品久久久久久蜜桃| 国产夫妻在线播放| 最近2019年好看中文字幕视频| 亚洲成人第一网站| 自拍av一区二区三区| 国产在线观看免费播放| 亚洲天天综合| 精品亚洲一区二区三区四区五区高| 午夜伦理大片视频在线观看| 91精品在线观看入口| 中文字幕91视频| 看片的网站亚洲| av在线观看地址| 这里视频有精品| 欧美激情2020午夜免费观看| 青青草超碰在线| 欧美一区二区私人影院日本| 国产成人在线视频观看| 亚洲欧洲日韩综合一区二区| 亚洲最大的黄色网| 一本色道久久综合亚洲精品高清 | 高清美女视频一区| 日韩免费看网站| 波多野结衣小视频| 亚洲第一成年网| 免费黄色国产视频| 国产精品中文字幕日韩精品| 欧美 日韩 国产一区| 欧美91精品| 97久久天天综合色天天综合色hd| 最新超碰在线| 精品国产伦一区二区三区观看方式 | 日日夜夜精品视频天天综合网| 免费看成人片| 国产麻豆一区| 日韩av成人在线| 在线免费看黄网站| 91麻豆精品国产91| 久草热在线观看| 欧美色道久久88综合亚洲精品| 久久精品无码一区| 99久久婷婷国产| 亚洲精品乱码久久久久久自慰| 亚洲婷婷免费| 日韩.欧美.亚洲| 日韩激情毛片| 国产在线观看不卡| 欧美精品videosex| 日韩高清中文字幕| 丰满人妻一区二区三区无码av | 九色视频成人自拍| 亚洲国产成人在线播放| 无码人妻精品一区二区三区蜜桃91| 国产精品色一区二区三区| 国偷自产av一区二区三区麻豆| 久久av资源网| 欧美丝袜在线观看| 亚洲永久在线| 宅男av一区二区三区| 精品毛片免费观看| 欧洲精品在线一区| 国产成人免费视频网站视频社区| 久久久久久午夜| 国产高清av在线| 亚洲午夜精品视频| 大乳在线免费观看| 欧美成人在线直播| 精品国产伦一区二区三区| 91精品国产手机| 国产成人av免费看| 日本韩国精品一区二区在线观看| 国产免费av一区| 一本到不卡精品视频在线观看| 成人免费毛片视频| 一区二区视频在线看| 欧美激情aaa| 欧美国产禁国产网站cc| 捆绑凌虐一区二区三区| 91在线观看视频| 韩国三级视频在线观看| 麻豆国产精品视频| 亚洲综合20p| 国产成都精品91一区二区三| 日韩av片网站| 国产一区二区三区四| 激情内射人妻1区2区3区| 激情综合激情| 国产午夜福利视频在线观看| 欧美另类女人| 黄色av网址在线播放| 中文字幕一区二区三区欧美日韩| 精品无码av无码免费专区| 日韩欧美精品一区| 黄黄视频在线观看| 亚洲精品系列| 免费在线观看毛片网站| 国产欧美午夜| 日本中文字幕亚洲| 欧美成人午夜| 咪咪色在线视频| 精品电影一区| 中文字幕永久视频| 国产乱码精品一区二区三区av | 一区二区三区中文字幕电影| 国产精品99无码一区二区| 亚洲另类在线视频| 国产成人无码一区二区三区在线| 亚洲午夜一区二区三区| 黄色一级片中国| 亚洲欧美一区二区久久| 97人人澡人人爽人人模亚洲| 精品污污网站免费看| 肥臀熟女一区二区三区| 一区二区三区视频免费| h网站视频在线观看| 欧美日本亚洲视频| 性欧美猛交videos| 国产精品aaaa| 乱亲女h秽乱长久久久| 亚洲女人毛片| 97精品一区| 一二三在线视频| 欧美精品二区| 三级在线视频观看| 精品亚洲国产成人av制服丝袜| 99久久免费看精品国产一区| 亚洲少妇中出一区| 精品视频一二三区| 欧美日本韩国一区| 日本午夜在线| 最新国产成人av网站网址麻豆| 成年男女免费视频网站不卡| 成人免费激情视频| 国产亚洲一区二区三区不卡| 一区不卡字幕| 老司机亚洲精品| 少妇网站在线观看| xnxx国产精品| 亚洲一级理论片| 一区二区在线免费| 懂色av.com| 日韩欧美国产麻豆| 日本精品在线| 国产精品香蕉av| 深爱激情综合网| 最新欧美日韩亚洲| 日本强好片久久久久久aaa| 一本加勒比北条麻妃| 欧美日韩国产一中文字不卡| 国产乱码77777777| 欧美一级欧美一级在线播放| 三级在线观看网站| 国产午夜精品全部视频播放| 午夜伦理福利在线| 国产精品一区二区av| 欧美激情日韩| 又大又长粗又爽又黄少妇视频| 亚洲欧美中日韩| 国产欧美久久久| 亚洲精品久久视频| eeuss鲁一区二区三区| 国产精品视频永久免费播放| 免费av一区二区三区四区| 日本黄色a视频| 国产日韩亚洲欧美精品| 182在线视频| 日韩欧美高清在线视频| 日韩大片b站免费观看直播| 欧美在线精品免播放器视频| 欧美男男freegayvideosroom| 免费成人午夜视频| 久久天天做天天爱综合色| 天堂网视频在线| 精品乱码亚洲一区二区不卡| www.亚洲.com| 97超碰蝌蚪网人人做人人爽| 少妇精品导航| 日本久久精品一区二区| av激情亚洲男人天堂| 99热国产在线观看| 欧美一级高清片| 福利成人导航| 久久伊人一区二区| 日日夜夜免费精品| 我要看一级黄色录像| 日韩免费高清av| 亚洲优女在线| 国产日韩欧美综合精品 | 亚洲综合999| 国产精品久久久午夜夜伦鲁鲁| 久久成人在线视频| 国内精品国产成人国产三级粉色 | 丰满白嫩尤物一区二区| 我要看一级黄色录像| 日韩精品一区二区三区三区免费 | 亚洲一区二区三区无吗| 国产免费a级片| 日本国产一区二区| a在线免费观看| 好吊色欧美一区二区三区视频| 日韩精品电影一区亚洲| 三级在线观看免费大全| 亚洲国产成人久久综合| 精品国产黄a∨片高清在线| 青草网在线观看| 国产视频在线观看一区二区三区| 在线能看的av| 久久精品电影网站| 国偷自产视频一区二区久| 亚洲娇小娇小娇小| 亚洲成人精品一区| 91xxx在线观看| 九九九九九九精品| 精品制服美女久久| 可以免费看的av毛片| 亚洲精品久久久久| 在线免费观看亚洲| 99精品在线免费视频| 97国产一区二区| 99热这里只有精品1| 国产精品成久久久久三级| 国精品一区二区|