Spaces:
Sleeping
Sleeping
File size: 9,124 Bytes
51da700 108a050 f1c51ab d16ab42 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
import gradio as gr
import torch
from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification
import pandas as pd
import plotly.express as px
import os
# --- 1. 模型加载 ---
# 负责同学: [填写负责这个模型的同学姓名,例如:张三]
# 注意:QuantFactory/Apollo2-7B-GGUF 模型通常不直接兼容 pipeline("text-generation", ...)
# 除非有额外的llama.cpp或特定的transformers加载配置。
# 为了演示和确保运行流畅,这里使用 gpt2-large 作为替代。
try:
model1_name = "gpt2-large" # 替代 QuantFactory/Apollo2-7B-GGUF 以确保兼容性
generator1 = pipeline("text-generation", model=model1_name, device=0 if torch.cuda.is_available() else -1)
print(f"✅ 模型 1 (文本生成: {model1_name}) 加载成功!")
except Exception as e:
print(f"❌ 模型 1 (文本生成: {model1_name}) 加载失败: {e}")
generator1 = None
# 负责同学: [填写负责这个模型的同学姓名,例如:李四]
# deepset/roberta-base-squad2 是一个问答模型,需要 context
try:
model2_name = "deepset/roberta-base-squad2"
qa_model = pipeline("question-answering", model=model2_name, device=0 if torch.cuda.is_available() else -1)
print(f"✅ 模型 2 (问答: {model2_name}) 加载成功!")
except Exception as e:
print(f"❌ 模型 2 (问答: {model2_name}) 加载失败: {e}")
qa_model = None
# --- 2. 推理函数 ---
# 这个函数现在接受一个问题/提示词和一个上下文
def get_model_outputs(question_or_prompt, context, max_length=100):
output_text_gen = "文本生成模型未加载或生成失败。"
output_qa = "问答模型未加载或生成失败。"
# 模型 1: 文本生成
if generator1:
try:
# 文本生成模型将问题和上下文作为其prompt的一部分
full_prompt_for_gen = f"{question_or_prompt}\nContext: {context}" if context else question_or_prompt
gen_result = generator1(full_prompt_for_gen, max_new_tokens=max_length, num_return_sequences=1, truncation=True)
output_text_gen = gen_result[0]['generated_text']
# 清理:移除输入部分,只保留生成内容
if output_text_gen.startswith(full_prompt_for_gen):
output_text_gen = output_text_gen[len(full_prompt_for_gen):].strip()
except Exception as e:
output_text_gen = f"文本生成模型 ({model1_name}) 错误: {e}"
# 模型 2: 问答
if qa_model and context: # 问答模型必须有上下文
try:
qa_result = qa_model(question=question_or_prompt, context=context)
output_qa = qa_result['answer']
except Exception as e:
output_qa = f"问答模型 ({model2_name}) 错误: {e}"
elif qa_model and not context:
output_qa = "问答模型需要提供上下文才能回答问题。"
return output_text_gen, output_qa
# Arena 选项卡内容创建函数 (40分)
def create_arena_tab():
with gr.Blocks() as arena_block:
gr.Markdown("## ⚔️ Arena: 模型实时对比")
gr.Markdown("在这里,您可以输入一个问题或提示词,并提供一段上下文。文本生成模型将根据问题和上下文生成文本,问答模型将从上下文中抽取答案。")
with gr.Row():
# 统一输入框 1: 问题/提示词
question_input = gr.Textbox(label="问题/提示词:", placeholder="请输入您的问题或想让模型生成的提示词...", lines=3)
# 统一输入框 2: 上下文 (主要用于问答模型)
context_input = gr.Textbox(label="上下文 (Context):", placeholder="请输入问答模型需要从中抽取答案的上下文...", lines=5)
with gr.Row():
# 增加生成长度控制(主要针对文本生成模型)
gen_length_slider = gr.Slider(minimum=20, maximum=300, value=100, step=10, label="文本生成最大长度")
generate_btn = gr.Button("🚀 生成并对比")
with gr.Row():
# 模型 1 输出 (文本生成)
output_text_gen = gr.Textbox(label=f"模型 1 (文本生成: {model1_name}) 输出:", interactive=False, lines=10)
# 模型 2 输出 (问答)
output_qa = gr.Textbox(label=f"模型 2 (问答: {model2_name}) 输出:", interactive=False, lines=10)
# 绑定按钮点击事件到推理函数
generate_btn.click(
fn=get_model_outputs,
inputs=[question_input, context_input, gen_length_slider],
outputs=[output_text_gen, output_qa]
)
return arena_block
# Report 选项卡内容创建函数 (30分)
# 报告内容直接嵌入到代码中
# def create_report_tab():
# report_content_markdown = """
# # 🚀 Hugging Face 模型对比实验报告
# ---
# ## 1. 模型及类别选择
# ### 1.1 所选模型的类型与背景说明
# 本次实验聚焦于**文本处理模型**,具体包括一个**通用文本生成模型**和一个**抽取式问答模型**。
# * **文本生成模型**能够根据输入的提示词(prompt)生成连贯、有意义的文本,广泛应用于自动写作、内容创作等。
# * **抽取式问答模型**则专注于从给定文本(上下文)中精确地定位并提取问题的答案,是信息检索和智能客服的核心技术。
# 近年来,随着Transformer架构的普及和大规模预训练技术的进步,这两类模型的性能都取得了显著提升。
# ### 1.2 模型用途对比简述
# 我们选择了以下 2 个模型进行对比:
# * **模型 1: GPT2-Large (文本生成模型)**
# * **用途简述**: 作为一个大型的通用文本生成模型, GPT2-Large 能够进行开放式文本生成、续写、摘要、创意写作等多种任务。它能理解较复杂的指令并生成语法流畅、内容丰富的文本。
# * **模型 2: deepset/roberta-base-squad2 (抽取式问答模型)**
# * **用途简述**: 这是一个专门用于抽取式问答任务的模型。它接收一个问题和一段上下文文本,然后从上下文中找到并返回问题的确切答案片段。主要应用于精准信息提取、文档问答系统等。
# ### 1.3 选取标准与模型异同点分析
# **选取标准**: 我们选择这两个模型主要基于以下标准:
# 1. **代表性**: 它们分别代表了文本处理领域中两种核心且不同的应用方向(生成与抽取)。
# 2. **可用性**: 模型在 Hugging Face Model Hub 上易于加载和使用 `pipeline`。
# 3. **性能对比潜力**: 两种不同类型的模型在 GRACE 维度上会有显著差异,有利于进行有深度的对比分析。
# **异同点分析**:
# * **相同点**:
# * 都基于 Transformer 架构。
# * 都处理自然语言文本作为输入。
# * 都可以在 Hugging Face `transformers` 库中通过 `pipeline` 方便地加载和使用。
# * **不同点**:
# * **任务类型**: GPT2-Large 专注于**文本生成**(从无到有),而 RoBERTa-SQuAD2 专注于**信息抽取**(从已有文本中找)。
# * **输入输出模式**:
# * GPT2-Large 接收一个提示词,输出一段新的、连贯的文本。
# * RoBERTa-SQuAD2 接收一个问题和一段上下文,输出上下文中最精确的答案片段。
# * **“创造性”**: GPT2-Large 具有更强的创造性,能够生成新的、未曾出现过的句子和想法;RoBERTa-SQuAD2 不具备创造性,它只从原文中抽取答案。
# * **对上下文的依赖**: 问答模型对上下文的依赖性极强,没有上下文就无法回答;文本生成模型则更灵活,即便没有明确上下文也能生成内容。
# ---
# ## 2. 系统实现细节
# ### 2.1 Gradio 交互界面截图
# 以下是我们在 Hugging Face Space 中构建的 Gradio 交互界面截图。
# 
# *(请将此处的图片链接替换为你实际上传到 Space Files 中的截图链接,例如:`/file/main/arena_screenshot.png`)*
# *说明:此图展示了我们构建的“Arena”选项卡界面。用户可以在左侧输入问题/提示词和上下文,右侧同步显示文本生成模型和问答模型的输出。*
# ### 2.2 输入与输出流程图
# ```mermaid
# graph TD
# A[用户输入: 问题/提示词] --> B{Gradio 界面};
# A --> C[用户输入: 上下文];
# C --> B;
# B -- 将问题与上下文合并为Prompt --> D1[调用 GPT2-Large (文本生成模型)];
# B -- 将问题与上下文分离 --> D2[调用 RoBERTa-SQuAD2 (问答模型)];
# D1 -- 生成文本 --> E1[GPT2-Large 输出];
# D2 -- 抽取答案 --> E2[RoBERTa-SQuAD2 输出];
# E1 --> F[在 Gradio 界面显示];
# E2 --> F;
# ```
# *说明:此流程图展示了用户输入如何被 Gradio 界面捕获,问题和上下文分别传递给两个模型。文本生成模型将两者合并为提示词,问答模型则分别使用它们,最终将各自的结果展示在界面上。* |