惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

RisingIce

2024年终总结 | RisingIce 使用Vercel搭建Umami统计 | RisingIce 部署Twikoo评论系统 | RisingIce Vercel域名被墙的问题 | RisingIce 修改anzhiyu主题的TianliGPT插件为其他大模型API | RisingIce Ubuntu挂载群晖共享文件夹与Comfyui模型迁移 | RisingIce 记一次conda环境激活却不起作用的问题及解决方法 | RisingIce 《程序员的README》- 随笔 | RisingIce Hello Word的由来 | RisingIce
使用大模型总结B站视频 | RisingIce
871996643@qq.com (RisingIce) · 2024-09-13 · via RisingIce

文章摘要 RisingIce

加载中...|

此内容由DeepSeek根据文章生成,未经过人工审核,仅用于文章内容的解释与总结 投诉

一、前言

由于之前白嫖的DeepSeek的API过期了,导致博客的AI摘要功能也报废了,于是咬咬牙斥巨资花了10块买了DeepSeek的500w的tokens。

但后面看着躺在自己账号的500w的tokens,觉得这些钱不花心里难受啊,于是便四处寻找能将这钱花出去的办法,某天在Langchain的Data Loader中发现一个奇怪的东西,没错,就是这玩意:BiliBiliLoader

简单来说它可以抓取B站视频的转录文本,然后将其转化为Document对象,而有了Document对象我们就可以做很多事情了,比如可以将Document对象丢给大模型,让大模型帮我们总结B站的视频内容。既然轮子别人都已经造好,只需要组装一下自己的跑车自行车就可以让其跑起来了,于是记录一下这个折腾的过程,当然项目已开源

二、基本实现过程

2.1 整体思路

实现的本质上是借助一种基于RAG(检索增强生成)思想优化大语言模型(LLM)输出的方法,让LLM能够实现检索到自搭建知识库的内容从而回答问题,增加LLM输出相关性以及减少大语言模型的幻觉(AI Hallucinations)问题,对于RAG感兴趣可以参考这篇文章:【RAG系统综述】|一文读懂RAG(检索增强生成)

前面提到通过RAG可以让LLM检索到自搭建知识库的内容,所以可以让LLM检索B站视频的内容,从而实现让LLM总结B站视频的效果,流程图大致如下:

2.2 BiliBili Loader

要使用BiliBili Loader首先要获取三个参数:sessdatabili_jctbuvid3

以Edge为例,首先需要登录B站账号,打开F12开发者工具应用程序 -> 存储 -> Cookie,选择B站的Cookie,右侧展开的信息找依次找到对应的三个参数值(注意不要泄露):

获取之后写段测试代码看是否能正常获取视频内容,测试代码如下:

python

from langchain_community.document_loaders import BiliBiliLoader
SESSDATA =""
BUVID3 = ""
BILI_JCT = ""
bv_id = "BV1iGpueKE26"
loader = BiliBiliLoader(
    [
        f"https://www.bilibili.com/video/{bv_id}",
    ],
    sessdata=SESSDATA,
    bili_jct=BILI_JCT,
    buvid3=BUVID3,
)
docs = loader.load()
print(docs[0].__dict__)

小手一抖,内容到手~

2.3 Document Split

由于B站的转录文档大多数没有固定的单词边界,所以使用RecursiveCharacterTextSplitter来对B站的转录文档进行切分,需要注意的是,如果使用RecursiveCharacterTextSplitter的方式来进行切分,则需要使用filter_complex_metadatametadata进行二次过滤,否则后面的Retrieve会报错,样例代码如下:

python

from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores.utils import filter_complex_metadata

text_splitter = RecursiveCharacterTextSplitter(
  chunk_size=1000,
  chunk_overlap=20
)
# 分割 bilbili documents
#docs为上面获取的bilbili documents
documents = text_splitter.split_documents(docs)
#二次过滤
docs_sec = filter_complex_metadata(documents=documents)

2.4 Embedding Model (可选)

切分文档之后,如果有其他情况可以使用预训练的向量模型对文档进行向量化,使用的是bert-base-chinese模型,(目前暂时只需要对单个的B站的视频转录文档进行总结,我并没有进行这一步,这里仅列出可能会出现的其他情况)

下载地址:google-bert/bert-base-chinese · Hugging Face

国内的可使用这个链接:google-bert/bert-base-chinese · HF Mirror (hf-mirror.com)

然后使用本地加载的方式运行bert-base-chinese,样例代码如下:

python

from langchain_huggingface import HuggingFaceEmbeddings
embed_model = HuggingFaceEmbeddings(
    #模型路径
    model_name = "model_path",
    #运行embeding模型的device,可选参数:['cuda','cpu',"mps", "npu"]
    model_kwargs = {'device': 'cuda'},
    encode_kwargs = {'normalize_embeddings': False}

)

from langchain.vectorstores import Chroma
#文档转化为向量值,并存储到chroma中
docsearch = Chroma.from_documents(docs_final, embed_model)

Ps:也可以使用Api的形式调用向量模型,这里不过多展开

2.5 Base Q&A

在进行最后总结之前,需要创建Prompt对LLM的输出做一定的提示,以及创建检索链,让LLM检索B站视频的内容进行最终的个人总结

Prompt示例如下:

python

default_prompt ="""请根据视频内容提炼并总结以下关键信息:
1. 视频的核心观点或论述(概述视频所传达的主要思想或立场),
2. 关键人物或事件(突出视频中涉及的重要角色或事件),
3. 视频的主线内容(梳理视频的整体逻辑和发展脉络,重点描述重要的情节或讨论的主题),
4.在总结的最后,提供你个人对视频内容的看法,包括你的评价、支持或质疑的原因,并简要解释为何持有此观点。
输出格式如下:
核心观点:
关键人物/事件:
主线内容:
个人看法:
"""

最终的函数代码示例如下:

python

from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
api_key = ""
api_base = ""
llm = ChatOpenAI(api_key=api_key,base_url = api_base,temperature=0, model_name="gpt-4")
#RAG文档抽取模板
RAG_TEMPLATE = """
   You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.
            <context>
            {context}
            </context>
            Answer the following question:
            {question}
"""

default_prompt ="""请根据视频内容提炼并总结以下关键信息:
1. 视频的核心观点或论述(概述视频所传达的主要思想或立场),
2. 关键人物或事件(突出视频中涉及的重要角色或事件),
3. 视频的主线内容(梳理视频的整体逻辑和发展脉络,重点描述重要的情节或讨论的主题),
4.在总结的最后,提供你个人对视频内容的看法,包括你的评价、支持或质疑的原因,并简要解释为何持有此观点。
输出格式如下:
核心观点:
关键人物/事件:
主线内容:
个人看法:
"""

def format_docs(docs):
        # 格式化文档列表,将每个文档的页面内容连接成一个字符串
        return "\n\n".join(doc.page_content for doc in docs)

# 加载提示模板
rag_prompt = ChatPromptTemplate.from_template(RAG_TEMPLATE)
# 创建检索链
rag_chain = (RunnablePassthrough.assign(context=lambda input: format_docs(input["context"]))
            | rag_prompt
            | llm
            | StrOutputParser()
        )
# 设置提问提示词
question_prompt = default_prompt
# 非流式处理
ans = rag_chain.invoke({"context": docs_final, "question": question_prompt})
print(ans)

最终的运行效果大概是这样的:

三、项目效果展示

启动项目

cmd

#启动FastAPI服务
uvicorn main:app --host 0.0.0.0 --port 3010

#启动Streamlit服务
streamlit run streamlit_ui/summary_ui.py

Ps:两种运行方法都是独立的,看情况二选一即可

3.1 FastAPI效果展示

请求路径:/bilismmary

请求标头:application/json

请求方法:POST

请求参数:

参数参数类型说明
bv_idstrB站视频的bv号
promptstr喂给LLM的总结Prompt,不写则采用默认参数
streambool是否开启流式输出,默认为False

响应参数(非流式):

参数参数类型说明
avidint视频的avid
bvidstr视频的bvid
cidint视频的分Pid
titlestr视频的标题
urlstr视频的链接
answerstr视频的总结内容

非流式请求示例:

json

{
    "bv_id":"BV1Wd4YeZEqG"
}

非流式响应示例:

json

{
    "avid": 113115312168779,
    "bvid": "BV1Wd4YeZEqG",
    "cid": 25640244589,
    "title": "国足1:2不敌沙特,天胡开局也能崩盘?",
    "url": "https://www.bilibili.com/video/BV1Wd4YeZEqG",
    "answer": "核心观点:\n视频主要讨论了中国足球队在与沙特队的比赛中,尽管开局有利,但最终以1:2不敌沙特,引发了关于教练伊万和中国足球未来的讨论。\n\n关键人物/事件:\n1. 伊万(教练)\n2. 中国队与沙特队的比赛\n3. 马图伊迪哈(法国世界杯冠军成员,观看比赛)\n\n主线内容:\n视频首先介绍了比赛前的氛围和球场的特点,随后详细描述了比赛的过程,包括中国队开局的有利情况和沙特队的红牌事件。接着,视频记录了比赛中的关键瞬间和球迷的反应,最终中国队被绝杀,赛后球场响起了要求教练下课的声音。\n\n个人看法:\n视频内容反映了足球比赛的不确定性和球迷的情感波动。尽管中国队开局有利,但最终失利,这凸显了足球比赛的不可预测性。个人认为,视频成功捕捉了比赛的紧张氛围和球迷的热情,但也暴露了中国足球在技术和战术上的不足。支持这一观点的原因是,视频中的比赛结果和球迷反应都指向了中国足球需要改进的方面。"
}

流式请求示例:

json

{
    "bv_id":"BV1kE4HesEUP",
    "stream":true
}

流式响应示例(部分):

3.2 StreamlitUI效果展示

打开项目streamlit地址:http://yourip:8502

界面如下:

左侧参数填写完整之后,右侧输入bv号,点击开始总结,即可看到效果

最终效果如下:

四、Todo List

目前项目还比较糙,等后续有时间了继续写Bug优化

  • 后续考虑使用多模态的LLM进行总结
  • 实现自动化的@一键总结
  • 微调Prompt,改善最终的回复效果
  • 优化代码中的错误判断
  • 编不出来了

五、总结

以上所展示的只是Langchain提供功能中的冰山一角,真正的潜力远不止于此。目前的这个项目只是抛砖引玉,算是个小小的开端。后续看看能否利用利用Langchain开发更多好玩的东西,还有就是这次的折腾仅仅只用掉了DeepSeek的20w的tokens,可恶啊