利用 vLLM 手擼一個多模態RAG系統

# 利用 vLLM 實現多模態RAG 系統 本文將深入探討如何使用 vLLM 構建多模態信息檢索與生成(Multimodal RAG)系統,以實現對包含文本、圖像和表格的文檔的有效處理和智能問答。 如果您想了解更多關于自然語言處理或其他技術領域的信息,請關注我們的公眾號 **柏企科技圈**。 ![](https://upload-images.jianshu.io/upload_images/17294212-917f4260e2848466.png) ## 一、多模態 RAG 概述 多模態 RAG 是一種先進的信息檢索和生成方法,它整合了多種內容類型,主要是文本和圖像。與傳統僅依賴文本的 RAG 系統不同,多模態 RAG 充分發揮了文本和視覺信息的優勢,為生成響應提供了更全面、更具上下文的基礎。 許多文檔,如研究論文、商業報告等,都包含文本、圖像、圖表和表格的混合。通過將視覺元素納入檢索和生成過程,多模態 RAG 系統能夠: 1. 捕捉純文本分析中丟失的細微差別; 2. 提供更準確、與上下文相關的響應; 3. 通過視覺輔助增強對復雜概念的理解; 4. 提高生成內容的整體質量和深度。 ## 二、多模態 RAG 的實現策略 實現多模態 RAG 管道有多種方法,各有其優勢和考慮因素: 1. **聯合嵌入和檢索** - 利用 CLIP(對比語言 - 圖像預訓練)或 ALIGN(大規模圖像和噪聲文本嵌入)等模型為文本和圖像創建統一的嵌入。 - 使用 FAISS 或 Annoy 等庫實現近似最近鄰搜索,以進行高效檢索。 - 將檢索到的多模態內容(原始圖像和文本塊)輸入到多模態大語言模型(如 LLaVa、Pixtral 12B、GPT - 4V、Qwen - VL)中進行答案生成。 2. **圖像到文本轉換** - 使用 LLaVA 或 FUYU - 8b 等模型從圖像生成摘要。 - 使用基于文本的嵌入模型(如 Sentence - BERT)為原始文本和圖像標題創建嵌入。 - 將文本塊傳遞給大語言模型進行最終答案合成。 3. **原始圖像訪問的混合檢索** - 采用多模態大語言模型從圖像生成文本摘要。 - 將這些摘要與原始圖像的引用以及其他文本塊一起嵌入和檢索。這可以通過帶有 Chroma、Milvus 等向量數據庫的多向量檢索器來實現,這些數據庫用于存儲原始文本、圖像及其摘要以便檢索。 - 對于最終答案生成,使用能夠同時處理文本和原始圖像輸入的多模態模型,如 Pixtral 12B、LLaVa、GPT - 4V、Qwen - VL。 在本文中,我們將探索第三種方法,利用一系列強大的工具組合來創建一個高效的多模態 RAG 系統。 ## 三、系統實現步驟 1. **工具準備** - **Unstructured**:用于解析各種文檔格式(包括 PDF)中的圖像、文本和表格。 - **LLaVa via vLLM**:由 vLLM 服務引擎驅動,使用名為 LLaVA(llava - hf/llava - 1.5 - 7b - hf)的視覺語言模型來處理文本/表格摘要以及多模態任務,如圖像摘要和從集成的文本和視覺輸入生成答案。雖然不是最先進的模型,但 LLaVA 效率高且計算成本低。借助 vLLM,它可以無縫部署在 CPU 上,對于那些希望在性能和資源效率之間取得平衡的人來說是一種理想的、具有成本效益的解決方案。 - **Chroma DB**:作為我們的向量數據庫,用于存儲文本塊、表格摘要、圖像摘要以及它們的原始圖像。結合其多向量檢索器功能,它為我們的多模態系統提供了強大的存儲和檢索系統。 - **LangChain**:作為協調工具,將這些組件無縫集成在一起。 通過結合這些工具,我們將展示如何構建一個強大的多模態 RAG 系統,該系統能夠處理不同類型的文檔,生成高質量的摘要,并生成利用文本和視覺信息的全面答案。 2. **數據下載** 我們將使用這篇博客文章作為文檔源,因為它包含以圖像形式呈現的圖表和表格中的有價值信息。 ```python import os import io import re import uuid import base64 import shutil import requests from tqdm import tqdm from PIL import Image import matplotlib.pyplot as plt from IPython.display import HTML, display from unstructured.partition.pdf import partition_pdf from langchain_core.documents import Document from langchain_text_splitters import CharacterTextSplitter from langchain.storage import InMemoryStore from langchain_chroma import Chroma from langchain.chains.llm import LLMChain, PromptTemplate from langchain_core.messages import HumanMessage, SystemMessage from langchain_core.prompts.chat import (ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate) from langchain_core.output_parsers import StrOutputParser from langchain_core.runnables import RunnableLambda, RunnablePassthrough from langchain.retrievers.multi_vector import MultiVectorRetriever from openai import OpenAI as OpenAI_vLLM from langchain_community.llms.vllm import VLLMOpenAI from langchain.embeddings import HuggingFaceEmbeddings embeddings = HuggingFaceEmbeddings(model_name='BAAI/bge-large-en') os.mkdir("data") shutil.move("gtm_benchmarks_2024.pdf", "data") ``` 3. **從 PDF 文檔中提取文本、表格和圖像** 下載 PDF 后,我們將利用 unstructured.io 庫處理文檔并提取內容。 ```python def extract_pdf_elements(path, fname): """ 從 PDF 文件中提取圖像、表格和文本塊。 path: 文件路徑,用于存儲圖像(.jpg) fname: 文件名 """ return partition_pdf( filename=path + fname, extract_images_in_pdf=True, infer_table_structure=True, chunking_strategy="by_title", max_characters=4000, new_after_n_chars=3800, combine_text_under_n_chars=2000, image_output_dir_path=path ) def categorize_elements(raw_pdf_elements): """ 將從 PDF 中提取的元素分類為表格和文本。 raw_pdf_elements: unstructured.documents.elements 列表 """ tables = [] texts = [] for element in raw_pdf_elements: if "unstructured.documents.elements.Table" in str(type(element)): tables.append(str(element)) elif "unstructured.documents.elements.CompositeElement" in str(type(element)): texts.append(str(element)) return texts, tables folder_path = "./data/" file_name = "gtm_benchmarks_2024.pdf" raw_pdf_elements = extract_pdf_elements(folder_path, file_name) texts, tables = categorize_elements(raw_pdf_elements) text_splitter = CharacterTextSplitter.from_tiktoken_encoder( chunk_size = 1000, chunk_overlap = 0 ) joined_texts = " ".join(texts) texts_token = text_splitter.split_text(joined_texts) print("文本塊數量:", len(texts)) print("表格元素數量:", len(tables)) print("分詞后的文本塊數量:", len(texts_token)) ``` 4. **生成表格摘要** 我們將使用在 CPU 機器上運行的 vLLM 引擎來驅動 7B 參數的 LLaVA 模型(llava - hf/llava - 1.5 - 7b - hf)生成表格摘要。我們也可以像在任何 RAG 系統中通常那樣使用基于文本的大語言模型,但在這里我們將使用能夠處理文本和圖像的 LLaVa 模型本身。 生成表格摘要是為了增強自然語言檢索,這些摘要對于高效檢索原始表格和文本塊至關重要。 ```python llm_client = VLLMOpenAI( base_url = "http://localhost:8000/v1", api_key = "dummy", model_name = "llava-hf/llava-1.5-7b-hf", temperature = 1.0, max_tokens = 300 ) def generate_text_summaries(texts, tables, summarize_texts=False): """ 總結文本元素 texts: 字符串列表 tables: 字符串列表 summarize_texts: 是否總結文本 """ prompt_text = """你是一個負責總結表格以便檢索的助手。 給出一個簡潔的、針對檢索進行優化的表格摘要。確保捕捉到所有細節。 輸入: {element} """ prompt = ChatPromptTemplate.from_template(prompt_text) summarize_chain = {"element": lambda x: x} | prompt | llm_client | StrOutputParser() text_summaries = [] table_summaries = [] if texts and summarize_texts: text_summaries = summarize_chain.batch(texts, {"max_concurrency": 3}) elif texts: text_summaries = texts if tables: table_summaries = summarize_chain.batch(tables, {"max_concurrency": 3}) return text_summaries, table_summaries text_summaries, table_summaries = generate_text_summaries( texts_token, tables, summarize_texts=False ) print("文本摘要數量:", len(text_summaries)) print("表格摘要數量:", len(table_summaries)) ``` 5. **生成圖像摘要** 現在,我們將使用視覺語言模型(VLM)生成圖像摘要。 注意:圖像可以通過兩種主要方式提供給模型:傳遞圖像鏈接或在請求中直接傳遞 base64 編碼的圖像。 ```python api_key = "dummy" base_url = "http://localhost:8000/v1" vlm_client = OpenAI_vLLM( api_key = api_key, base_url = base_url ) def encode_image(image_path): """獲取 base64 字符串""" with open(image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode("utf-8") def image_summarize(img_base64, prompt): """生成圖像摘要""" chat_response = vlm_client.chat.completions.create( model="llava-hf/llava-1.5-7b-hf", max_tokens=1024, messages=[{ "role": "user", "content": [ {"type": "text", "text": prompt}, "type": "image_url", "image_url": { "url": f"data:image/jpeg;base64,{img_base64}", }, }, ], stream=False ) return chat_response.choices[0].message.content.strip() def generate_img_summaries(path): """ 為圖像生成摘要和 base64 編碼字符串 path: Unstructured 提取的.jpg 文件路徑列表 """ img_base64_list = [] image_summaries = [] prompt = """你是一個負責總結圖像以便最佳檢索的助手。 這些摘要將被嵌入并用于檢索原始圖像。 編寫一個清晰簡潔的摘要,捕捉所有重要信息,包括圖像中的任何統計數據或關鍵點。""" for img_file in tqdm(sorted(os.listdir(path))): if img_file.endswith(".jpg"): img_path = os.path.join(path, img_file) base64_image = encode_image(img_path) img_base64_list.append(base64_image) generated_summary = image_summarize(base64_image, prompt) print(generated_summary) image_summaries.append(generated_summary) return img_base64_list, image_summaries img_base64_list, image_summaries = generate_img_summaries(folder_path) assert len(img_base64_list) == len(image_summaries) ``` 6. **存儲和索引文檔摘要** 為了配置多向量檢索器,我們將原始文檔(包括文本、表格和圖像)存儲在文檔存儲中,同時在向量存儲中索引它們的摘要,以提高語義檢索效率。 ```python def create_multi_vector_retriever( vectorstore, text_summaries, texts, table_summaries, tables, image_summaries, images ): """ 創建索引摘要但返回原始圖像或文本的檢索器 """ store = InMemoryStore() id_key = "doc_id" retriever = MultiVectorRetriever( vectorstore=vectorstore, docstore=store, id_key=id_key ) def add_documents(retriever, doc_summaries, doc_contents): doc_ids = [str(uuid.uuid4()) for _ in doc_contents] summary_docs = [ Document(page_content=s, metadata={id_key: doc_ids[i]}) for i, s in enumerate(doc_summaries) ] retriever.vectorstore.add_documents(summary_docs) retriever.docstore.mset(list(zip(doc_ids, doc_contents))) if text_summaries: add_documents(retriever, text_summaries, texts) if table_summaries: add_documents(retriever, table_summaries, tables) if image_summaries: add_documents(retriever, image_summaries, images) return retriever vectorstore = Chroma( collection_name="mm_rag_vectorstore", embedding_function=embeddings, persist_directory="./chroma_db" ) retriever_multi_vector_img = create_multi_vector_retriever( vectorstore, text_summaries, texts, table_summaries, tables, image_summaries, img_base64_list ) ``` 7. **多向量檢索設置** 接下來,我們定義處理和處理文本數據和 base64 編碼圖像的函數和配置,包括調整圖像大小和格式化模型提示。它設置了一個多模態檢索和生成(RAG)上下文鏈,以集成和分析文本和圖像數據來回答用戶查詢。 由于我們使用 vLLM 的 HTTP 服務器為視覺語言模型提供服務,該服務器與 OpenAI 視覺 API(聊天完成 API)兼容,因此為了設置模型的上下文,我們遵循特定的聊天模板。 ```python def plt_img_base64(img_base64): """顯示 base64 編碼字符串為圖像""" image_html = f'' display(HTML(image_html)) def looks_like_base64(sb): """檢查字符串是否看起來像 base64""" return re.match("^[A-Za-z0-9+/]+[=]{0,2}$", sb) is not None def is_image_data(b64data): """ 通過查看數據開頭檢查 base64 數據是否為圖像 """ image_signatures = { b"\xff\xd8\xff": "jpg", b"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a": "png", b"\x47\x49\x46\x38": "gif", b"\x52\x49\x46\x46": "webp" } try: header = base64.b64decode(b64data)[:8] for sig, format in image_signatures.items(): if header.startswith(sig): return True return False except Exception: return False def resize_base64_image(base64_string, size=(64, 64)): """ 調整 base64 編碼圖像的大小 """ img_data = base64.b64decode(base64_string) img = Image.open(io.BytesIO(img_data)) resized_img = img.resize(size, Image.LANCZOS) buffered = io.BytesIO() resized_img.save(buffered, format=img.format) return base64.b64encode(buffered.getvalue()).decode("utf-8") def split_image_text_types(docs): """ 拆分 base64 編碼圖像和文本 """ b64_images = [] texts = [] for doc in docs: if isinstance(doc, Document): doc = doc.page_content if looks_like_base64(doc) and is_image_data(doc): doc = resize_base64_image(doc, size=(64, 64)) b64_images.append(doc) else: texts.append(doc) return {"images": b64_images, "texts": texts} def img_prompt_func(data_dict): """ 將上下文合并為單個字符串 """ formatted_texts = "\n".join(data_dict["context"]["texts"]) messages = [] text_message = { "type": "text", "text": ( "你是一個在金融和商業指標方面有專長的助手。\n" "你將獲得可能包括與業務績效和行業趨勢相關的文本、表格和圖表的信息 ## 四、檢索測試 我們提出問題:“從 2020 年到 2024 年,公共 SaaS 公司的年收入同比中位數增長率發生了怎樣的變化?” ```python query = "How has the median YoY ARR growth rate for public SaaS companies changed from 2020 to 2024?" docs = retriever_multi_vector_img.invoke(query) plt_img_base64(docs[0]) ``` ## 五、運行 RAG 管道生成答案 由于我們當前的模型不支持非常長的上下文以及每個文本提示包含多個多模態項目,所以我們將修改檢索到的上下文并測試最終答案合成部分。 ```python context = chain_multimodal_context.invoke(query)[0].content context = [ { 'type': 'text', 'text': "You are an AI assistant with expertise in finance and business metrics.\nYou will be given information that may include text, tables, and charts related to business performance and industry trends.\nYour task is to analyze this information and provide a clear, concise answer to the user's question.\nFocus on the most relevant data points and insights that directly address the user's query.\nUser's question: How has the median YoY ARR growth rate for public SaaS companies changed from 2020 to 2024?" }, { 'type': 'image_url', 'image_url': {'url': 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABAAEADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3wRoQOP1o8pPT9abFKX3Axuu1toJH3vce1SbvY0AN8pPT9axf7Zn+0zQDQr/MblRIQAjjdjcDnp0P0zW5u9jUVxCtxCY2MqAkHdG20j8RQBiW2uXM0sUcvh7UIfMkCbiAVQZI3Me3Az3re8pPT9aZbwi2iEatK4BJzI248+9S7vY0AN8pPT9arXcy20lqnlFvPl8rO7G35Sc+/TH41b3exqKWJJWV2D5UHGGIH5U1bqJ3toLHMj7gA3yNtOVI5x29arpq9hI1uqXSObgssW3kOV+8AfaoLxhLc2ssDXDyQSMhjiYKmSv/AC0J7fnyaZDY3SpEPNsLZUZjtt7fkA/3STgHpk45pDLFpq1tdRW7MHt5JywjhnXa7bevH61cWVHUMjBlPQryDWYbG5hlhZJ4bsRlvmu1/eLn+66jj8qr2TPZzWdnElvZRIJDLbM5cv3Bjbv6n69KAN3cPf8AI0bh7/karWWoW2oWkdzA+Y5ASu4bTwcdDVncv94UAG4e/wCRpCwIPXp6Uu5fUUhYEHkdKAESRGBCupKna2D0PoadkeopqKgBKquSctgd/enYHoKADI9RUU8ENygWVQcHKnOCp9QexqXA9BRgegoAxZLWeG6tp50N60CuqXKHa8efVBw31Hp0qXT724lhtPKkiv4WV/OuVYKVPVRt/TtWrgegqtPp1pczpPLCDMgIWRSVYA+457UAV4NTnn+yg6dcRmeN2bfj90R0DfXtSQXGpyS2wntYIY3iYzjzdzI+eAvqP8aeukQARhpryRUUrh7lyD06889Kkt9MsbIA21pDEyIUDKg3BeOM9ew/KgCxHDGm4qigudzEDqfWn7V9BVKS33TJJFcCNScyLyd/AHrx0pi2so8vdfBsZ3/Ljd+vFAGhtX0FG1fQVnrayjZuvw2M7vlxu/XihbWYeXuvw20Hf8uN3p34oA0Nq+go2r6Cs9bWYbN1+DgHd8v3vTvxQtrMNmb8HCkN8uNx7HrxjigDQ2r6CkKgA8DpVAWsw2ZvwcKQ3y9Tzg9eMcflTo7eVHjZr0OFB3rtxuPPPXjt+VAH/9k=' } ] chat_response = vlm_client.chat.completions.create( model="llava-hf/llava-1.5-7b-hf", messages=[{ "role": "user", "content": context }], stream=True ) for chunk in chat_response: if chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end="", flush=True) ``` 基于提供的用戶問題以及檢索到的文本片段和圖像,模型現在將開始流式輸出其響應。 ## 六、注意事項 為了演示圖像檢索,最初生成了較大(4k 令牌)的文本塊,然后進行了總結。然而,情況并非總是如此,可能需要其他方法來確保準確和高效的分塊和索引。 總結和答案質量似乎對圖像大小和分辨率敏感。 當前使用的視覺語言模型僅支持單圖像輸入。 模型可能難以理解某些視覺元素,如圖表或復雜的流程圖。 在某些情況下,模型可能會生成錯誤的描述或標題。例如,在詢問統計問題時可能會提供錯誤信息。 如果圖像中的文本不清晰或模糊,模型將盡力解釋,但結果可能不太準確。 ## 七、未來展望 使用具有更長上下文窗口且支持每條消息傳遞多個圖像和/或傳遞多輪對話的視覺語言模型(如 Pixtral - 12B)測試準確性。 實現文本和圖像模態之間更復雜的交互,使模型能夠根據問題動態地優先考慮視覺或文本信息。 引入更精細的視覺內容總結技術,以生成更好的圖像語義表示。 由于我們使用 vLLM 來提供模型服務,研究在 CPU 和 GPU 上使用不同優化運行相同模型時性能的變化將是很有趣的。 最后但同樣重要的是,使用更好的分塊和檢索機制。 > 如果您對文中的技術細節或代碼實現有任何疑問,歡迎隨時交流探討。同時,我們也將持續關注 RAG 技術的發展動態,為您帶來更多的前沿資訊和深度分析。 > > 以上就是本文的全部內容,希望對您有所幫助!如果您想了解更多關于自然語言處理或其他技術領域的信息,請關注我們的公眾號 **柏企科技圈**。 ## 參考文獻 - https://blog.langchain.dev/semi-structured-multi-modal-rag/ - https://github.com/langchain-ai/langchain - https://python.langchain.com/docs/how_to/multi_vector/ - https://docs.vllm.ai/en/latest/models/vlm.html - https://platform.openai.com/docs/guides/vision - https://cs.stanford.edu/~myasu/blog/racm3/ # 推薦閱讀 [1. 專家混合(MoE)大語言模型:免費的嵌入模型新寵](https://mp.weixin.qq.com/s/XwgigFEuyD-ED3IunlSItw?token=2113630118&lang=zh_CN) [2. LLM大模型架構專欄|| 從NLP基礎談起](https://mp.weixin.qq.com/s/MYx5V29WczQzxPybKBbT7Q?token=2113630118&lang=zh_CN) [3. AI Agent 架構新變革:構建自己的 Plan-and-Execute Agent](https://mp.weixin.qq.com/s/NBlp058THkckTKFscjPhiw?token=2113630118&lang=zh_CN) [4. 探索 AI 智能體工作流設計模式](https://mp.weixin.qq.com/s/gQuxYo7LiKuAWr04hzIjQg?token=2113630118&lang=zh_CN) [5. 探秘 GraphRAG:知識圖譜賦能的RAG技術新突破](https://mp.weixin.qq.com/s/MtTju5IQ9alTwZP_xAK-bg?token=1679189915&lang=zh_CN) [6. 解鎖 RAG 技術:企業數據與大模型的完美融合之道](https://mp.weixin.qq.com/s/9KdLmYj7WbbkMfljWMXvTg?token=1679189915&lang=zh_CN) 本文由[mdnice](https://mdnice.com/?platform=6)多平臺發布
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,835評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,676評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,730評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,873評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,266評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,482評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,036評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,846評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,025評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,279評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,751評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,016評論 2 375

推薦閱讀更多精彩內容