[Datawhale AI夏令营] —— 星火大模型驱动阅读理解题库构建挑战赛:模型微调

Datawhale 学习指南:https://linklearner.com/activity/14/12/26
赛事链接:https://challenge.xfyun.cn/topic/info?type=question-bank-construction&ch=dw24_E7x9gl
星火大模型驱动阅读理解题库构建挑战赛baseline:https://aistudio.baidu.com/projectdetail/8225663

1. 赛事解释

参考文献:https://challenge.xfyun.cn/topic/info?type=question-bank-construction&ch=dw24_E7x9gl

以下内容为自己阅读论文以及查阅资料后的理解,如果存在问题欢迎大家进行交流讨论

1.1 赛事背景

在教育领域,传统的出题方式通常依赖于教师的个人经验和教学大纲的要求。这种方式尽管长期以来被广泛应用,且在某些程度上稳定可靠,但也存在一些明显的局限性。例如,传统出题往往难以提供足够的多样性和个性化设计,无法完全满足学生们在不同学习能力和兴趣方向上的需求。尤其在大班教学中,出题方式的单一性很可能会导致部分学生无法通过练习获得最佳的学习效果。

此外,教师在设计试题时,通常需要投入大量的时间和精力。从教材的选材、题目的设计,到题目难度的平衡,这一过程不仅繁琐,且效率较低。这对于教学资源有限的学校和教师来说,无疑是一种负担,可能影响教育资源的有效分配。

然而,随着人工智能技术的快速发展,特别是大模型的出现,教育领域正在发生深刻的变革。大模型作为一种先进的技术工具,正成为推动个性化学习与智能教育的重要力量。尤其是在语言学科的教学中,利用大模型完成Question Answer Generation (QAG) 过程,可以有效地赋能QA题型的出题流程,解决传统出题方式的诸多痛点。

作为一名对教育技术充满热情的开发者,我深感大模型在这一领域的巨大潜力。因此,我决定参与此次竞赛,希望通过我的技术知识和创新思维,为我国的教育发展“提质增效”。

1.2 赛事任务

本次竞赛的核心任务是基于大模型微调技术,微调适用于高考语文现代文阅读 和 英语阅读的QAG模型,以实现输入文章、输出问题与答案的目标。为了帮助参赛者顺利完成任务,大赛还提供免费的模型微调服务平台,为团队提供技术支持。

1.3 知识点应用与文体分析

在参与这一任务时,我们需要深入理解和应用以下几个关键知识点:

  1. 大模型微调技术:大模型(如GPT系列模型)的微调是指在已经训练好的预训练模型基础上,通过在特定任务上的数据进行进一步训练,以使模型更适应特定的应用场景。对于QAG任务而言,我们需要微调模型,使其能够根据高考语文现代文阅读和英语阅读材料,自动生成相关的问题与答案。

  2. 自然语言处理(NLP):QAG任务涉及文本理解、信息抽取与生成,这都属于自然语言处理的范畴。模型需要具备强大的文本分析能力,能够理解输入的阅读材料,并生成合适的提问与答案。

  3. 深度学习与神经网络:模型的微调过程基于深度学习技术,主要通过神经网络来实现。参赛者需要熟悉如何设置和优化模型的参数,如何使用大规模数据进行训练,以及如何评估模型的表现。

  4. 高考语文与英语阅读:对于参赛者来说,了解高考语文与英语阅读的命题规律与考试特点至关重要。我们需要分析近年来高考中出现的题型,特别是阅读理解部分,以确保生成的问题与答案符合考试要求和学生的认知水平。

1.4 研究现状与挑战

目前,大模型在生成问题与答案方面已经取得了一定进展。许多研究表明,基于预训练语言模型(如GPT-3、T5等)的QAG系统能够生成高质量的问题与答案。然而,在特定的考试场景中,仍然存在一些挑战:

  1. 生成问题的准确性与合理性:虽然大模型在生成自然语言文本方面表现出色,但生成的问题是否能够准确反映阅读材料的重点,并在难度上符合考试要求,仍然需要仔细微调和评估。

  2. 生成答案的准确性:模型生成的答案是否准确、完整,能否有效帮助学生理解问题,同样是一个重要的考量标准。尤其在高考语文和英语的阅读理解中,答案的准确性至关重要。

  3. 模型的泛化能力:大模型往往在特定的训练数据上表现出色,但在面对新颖或不同风格的文本时,生成结果可能不理想。参赛者需要通过多样化的训练数据,提高模型的泛化能力,以应对不同类型的阅读材料。

1.5 解决方案与展望

为了解决上述挑战,我计划采用以下策略:

  1. 数据准备:收集并整理大量与高考语文现代文阅读和英语阅读相关的练习题目和答案,作为模型微调的训练数据。同时,确保数据的多样性,以提高模型的泛化能力。

  2. 模型微调:利用大赛提供的微调平台,对预训练模型进行进一步的训练和优化。通过多次实验,调整模型参数,使其生成的问题和答案更加准确、合理。

  3. 模型评估与改进:在训练过程中,我将使用特定的评估指标,如BLEU、ROUGE等,评估模型的生成效果。通过不断调整与改进,力求生成的题目和答案达到高考标准。

  4. 创新应用:如果模型能够成功微调并生成高质量的问题与答案,我希望将这一成果应用于更广泛的教育场景中,如在线教育平台、智能学习系统等,进一步推动个性化学习的实现。

总的来说,这次竞赛不仅是对我个人技术能力的挑战,更是一次为教育领域做出贡献的宝贵机会。我期待通过大模型微调技术的应用,创造出更智能、更高效的出题方式。

2. 数据处理

数据下载链接:https://challenge.xfyun.cn/topic/info?type=question-bank-construction&option=stsj&ch=dw24_E7x9gl
数据处理链接:https://aistudio.baidu.com/projectdetail/8225663

2.1 数据处理的重要性与方法论

在这次大赛中,需要面对的首要任务是对提供的高考语文现代阅读和英语阅读数据集进行有效的处理。这些数据集不仅包括原文、题目和答案,而且涵盖了近几年的高考真题材料,对我们进行模型训练和测试至关重要。

2.1.1 知识点和技术概览

在处理数据集的过程中,我主要应用了以下几个关键的知识点和技术:

  1. 数据清洗:这一步骤涉及去除数据中的噪声和不相关信息,如无关字符、格式错误等。此外,数据清洗还包括统一数据格式,使其符合后续处理的需要。

  2. 数据整理:将数据转换成训练所需的格式,即“input/target”的结构。这里的“input”通常是包含一段阅读文章和一个相关的prompt(如:“根据以下阅读文本出题”),而“target”则是相对应的题目和答案。

  3. 自然语言处理(NLP)技术:在整理数据的过程中,我利用NLP技术进行文本分析,比如词频分析和关键词提取,以优化prompt并确保生成的问题与原文内容高度相关。

2.1.2 文体和数据格式

大模型训练要求数据不仅要准确,还需要保持一定的文体连贯性。在这里,我主要处理的文体包括教育考试语言,这种文体通常包括严谨的叙述以及明确的问题和答案格式。此外,高考语文现代阅读往往包含文学评论、议论文等类型,而英语阅读则涵盖了叙述文、说明文等,这要求我在处理数据时保持对不同文体的敏感性。

2.1.3 现有研究和创新点

根据现有的研究,大模型如GPT和BERT已被广泛应用于语言生成和理解任务中。这些模型能够处理大量的文本数据并生成连贯的文本内容。然而,面对特定如高考这样的应用场景时,这些模型往往需要针对性的调整和优化,这是我的主要创新点之一。

我计划通过引入更多高质量的外部数据,如历年的高考试题和优秀的模拟题,来扩充训练数据集。同时,我将开发一个算法,专门用于优化问题生成的相关性和多样性,以提高模型对高考题型的适应性。

2.1.4 解决方案与实施步骤

为了解决赛事问题,我设定了以下实施步骤:

  1. 数据收集与清洗:首先,我将从大赛指定的下载页面获取数据集,然后进行初步的清洗工作,去除所有明显的错误和不一致性。

  2. 数据整理与格式化:接下来,我将数据转换成“input/target”的格式,确保每个“input”都附带正确的prompt,而每个“target”都精确地反映了对应的问题和答案。

  3. 模型训练与微调:利用提供的讯飞大模型定制训练平台,我将对模型进行微调,确保它能够理解和生成与高考阅读材料相匹配的问题和答案。

  4. 测试与优化:在模型训练后,我将对其进行严格测试,评估其在生成问题和答案方面的效能。基于测试结果,我将进一步调整模型参数,优化其性能。

通过这些步骤,我希望能够开发出一个强大的Q&A生成工具,为教育界提供有效的支持,同时也为自己在AI和教育技术领域的探索中开辟新的道路。

2.2 数据集说明

对数据集进行展示,以便后续理解代码。
在这里插入图片描述
在这里插入图片描述

2.3 安装库

!pip install pandas openpyxl

这行代码是用于在Python环境中安装两个库:pandasopenpyxl

  • pandas 是一个强大的数据分析和操作库,提供了许多便捷的数据结构和数据操作方法,非常适合进行数据清洗、分析和可视化等工作。
  • openpyxl 是一个用于读写 Excel 2010 xlsx/xlsm/xltx/xltm 文件的库,使得可以直接通过Python操作Excel文件。

在命令行中使用 !pip install 命令,可以调用Python包管理器 pip 来安装这些库。这样,你就可以在Python脚本或者Jupyter笔记本等环境中利用这些库的功能了。如果你是在Jupyter笔记本中运行这个命令,那么在命令前添加 ! 符号是为了告诉笔记本这是一个系统命令,而不是Python代码。

2.4 语文问答数据制作

2.4.1 读取Excel

# coding~

import pandas as pd
import re

# 读取Excel文件
df = pd.read_excel('训练集-语文.xlsx')
df = df.replace('.', '.', regex=True)
df = df.replace('(', '(', regex=True)


# 读取第二行(即第三行)“选项”列的内容
second_row_option_content = df.loc[2, '选项']

# 显示第二行“选项”列的内容
print(second_row_option_content)
7.下列对文本相关内容和艺术特色的分析鉴赏,不正确的一项是(3分)
A.作者在写南国的风物时,用了“那一块一块的稻田”那-堆-堆的房屋”等,语言的节奏感符合火
车行进时的动态感。
B.作者认为车过潭江的部分是“新宁铁路中的一段最美丽的工程”,既在于这里风景的优美,更在于
工程体现了机械的诗意。
C.作者认为如果只把“月夜”“ 花朝”“青山” 一类的东西当作写诗的材料,其实是不懂诗,依
据是这些材料本身缺乏生命力.
D.“诗应该给人以创造的喜悦,诗应该散布生命”是作者对诗的认识,也是他认为机械具有诗意的一一
个重要前提.
8.本文在写“机械的诗”时再写到工人,请简要分析二者之间的内在联系。(6分)
9.这篇随笔的最后段跳转到作者在上海的生活见闻,这样写有什么好处?请结合文本简要分析.

这段代码用于处理Excel文件中的数据,具体功能如下:

  1. 导入库

    • import pandas as pd: 导入pandas库,通常用于数据分析和操作,这里简称为pd
    • import re: 导入正则表达式库,用于执行与正则表达式相关的操作。
  2. 读取Excel文件

    • df = pd.read_excel('训练集-语文.xlsx'): 使用pandas库的read_excel函数读取名为训练集-语文.xlsx的Excel文件,将数据加载到DataFrame df中。
  3. 数据清洗

    • df = df.replace('.', '.', regex=True): 在整个DataFrame中,将所有的中文句号替换为英文句号.。这里设置regex=True表示启用正则表达式进行匹配。
    • df = df.replace('(', '(', regex=True): 将所有的中文左括号替换为英文左括号(。同样使用正则表达式进行匹配。
  4. 读取特定数据

    • second_row_option_content = df.loc[2, '选项']: 使用.loc属性从DataFrame df中获取位于第三行(索引为2,因为索引从0开始)的“选项”列的内容,并将其存储在变量second_row_option_content中。
  5. 输出结果

    • print(second_row_option_content): 打印变量second_row_option_content的内容,即第三行的“选项”列的内容。

这段代码主要用于从Excel文件读取数据,并进行一些基本的文本替换清洗,最后提取特定行列的数据进行展示。

2.4.2 提取选择题中问题信息

def chinese_multiple_choice_questions(questions_with_answers):
    # 输入的题目文本
    text = questions_with_answers

    # 正则表达式模式
    question_pattern = re.compile(r'\d+\..*?(?=\d+\.|$)', re.DOTALL)
    choice_pattern = re.compile(r'([A-D])\s*(.*?)(?=[A-D]|$|\n)', re.DOTALL)

    # 找到所有问题
    questions = question_pattern.findall(text)

    # 初始化选择题和简答题列表
    multiple_choice_questions = []
    short_answer_questions = []

        # 处理每个问题
    for id,question in enumerate(questions):
        # 检查是否是选择题
        if re.search(r'[A-D]', question):
            
            choices = choice_pattern.findall(question)
            question_text = re.split(r'\n', question.split('(')[0])[0]
            
            
            pattern_question = re.compile(r'(\d+)\.(.*)')
            matches_question = str(id+1)+'.'+ pattern_question.findall(question_text)[0][1] # 取出问题后重排序
            # print(str(id+1)+'.'+matches_question)
            
            multiple_choice_questions.append({
                'question': matches_question,
                'choices': choices
            })
        else:
            short_answer_questions.append(question.strip())
    return multiple_choice_questions

这段代码定义了一个函数 chinese_multiple_choice_questions,用于从给定文本中解析出选择题和简答题。它首先使用正则表达式识别并分割文本中的问题,然后区分选择题和简答题

  1. 读取并处理输入文本:通过正则表达式识别文本中的各个问题,每个问题以数字和点开始。

  2. 分类问题:通过检查问题中是否包含A-D来判断是否为选择题。如果是选择题,进一步使用正则表达式抽取选项并清洗问题文本,否则视为简答题。

  3. 存储问题:将选择题存储在一个列表中,每个元素包含问题文本和对应选项。简答题则简单地存储问题文本。

  4. 返回结果:函数返回一个列表,其中包含所有处理好的选择题,每个选择题包括一个整理好的问题文本和相应的选项。简答题虽然在这段代码中被处理,但并未返回。

整体来看,这个函数对提供的文本进行了有效的结构化处理,方便后续对选择题的进一步使用和分析。

questions_list = []
for data_id in range(len(df[:3])):
    second_row_option_content = df.loc[data_id, '选项']
    questions_list.append(chinese_multiple_choice_questions(second_row_option_content))

这段代码的功能是从一个DataFrame df 中提取前三行的“选项”列内容,并使用先前定义的 chinese_multiple_choice_questions 函数解析每行的内容以构造选择题列表:

  1. 初始化列表

    • questions_list = []:创建一个空列表questions_list,用来存放解析后的选择题数据。
  2. 循环处理DataFrame中的行

    • for data_id in range(len(df[:3])):循环遍历DataFrame df 的前三行。df[:3]表示取df的前三行,range(len(df[:3]))生成一个从0到2的整数序列,用于索引行。
  3. 提取并解析数据

    • second_row_option_content = df.loc[data_id, '选项']:使用.loc方法从DataFrame中获取当前data_id指定的行的“选项”列的内容,存储在变量second_row_option_content中。
    • chinese_multiple_choice_questions(second_row_option_content):调用chinese_multiple_choice_questions函数,将提取出的“选项”列内容作为参数传入,用以解析选择题。
  4. 存储解析结果

    • questions_list.append(...):将通过chinese_multiple_choice_questions函数解析出的选择题添加到questions_list列表中。

最终,questions_list将包含前三行数据中每行对应的选择题解析结果。这个代码块实现了从DataFrame中提取特定数据并进行处理的目的,适用于从结构化数据源中批量处理和解析选择题数据。

2.4.3 提取选择题中回答信息

def chinese_multiple_choice_answers(questions_with_answers):
    questions_with_answers = questions_with_answers.replace(" ", "").replace("\n", "")
    
    # print(questions_with_answers)
    # 使用正则表达式匹配答案
    choice_pattern = re.compile(r'(\d+)\.([A-Z]+)')
    short_pattern = re.compile(r'(\d+)\.([^A-Z]+)')

    # 找到所有匹配的答案
    choice_matches = choice_pattern.findall(questions_with_answers)
    short_matches = short_pattern.findall(questions_with_answers)

    # 将匹配结果转换为字典
    choice_answers = {int(index): answer for index, answer in choice_matches}
    short_answers = {int(index): answer for index, answer in short_matches}

    # 按序号重新排序
    sorted_choice_answers = sorted(choice_answers.items())
    sorted_short_answers = sorted(short_answers.items())
    
    answers = []

    # 输出结果
    
    # print("选择题答案:")
    for id in range(len(sorted_choice_answers)):
        answers.append(f"{id+1}. {sorted_choice_answers[id][1]}")
    return answers

这个函数 chinese_multiple_choice_answers 的目的是从提供的文本中解析出选择题和简答题的答案,并以列表形式返回选择题答案:

  1. 文本预处理

    • 将输入的字符串 questions_with_answers 中的所有空格和换行符替换掉,以便更准确地进行正则表达式匹配。
  2. 正则表达式匹配答案

    • choice_pattern = re.compile(r'(\d+)\.([A-Z]+)'):定义一个正则表达式来匹配选择题答案,格式为数字后跟点和一个或多个大写字母(A-Z),例如 “1.ABC”。
    • short_pattern = re.compile(r'(\d+)\.([^A-Z]+)'):定义一个正则表达式来匹配非选择题(如简答题)答案,格式为数字后跟点和非大写字母序列。
  3. 查找所有匹配项

    • choice_matchesshort_matches:使用上述正则表达式在处理后的文本中找到所有匹配的答案。
  4. 结果转换为字典

    • choice_answersshort_answers:将找到的答案转换为字典格式,其中键是题号(转换为整数类型),值是答案字符串。
  5. 答案排序

    • 使用 sorted() 函数根据题号对答案进行排序。
  6. 输出结果

    • 循环遍历排序后的选择题答案,并格式化为 “题号. 答案” 的形式,存储在列表 answers 中。
  7. 返回选择题答案

    • 函数最终返回包含所有选择题答案的列表 answers,格式化为 “1. ABC” 等形式。

该函数主要用于从格式化文本中提取和处理选择题和简答题的答案,但当前实现中仅返回选择题答案,简答题答案虽被解析但未用于最终输出。

# 读取第二行(即第三行)“选项”列的内容
second_row_option_content = df.loc[60, '答案']

# 显示第二行“选项”列的内容
print(second_row_option_content)


chinese_multiple_choice_answers(second_row_option_content)
4.B
5.窗子既是指现实世界中的窗子,可以是铁纱窗,或者是玻璃窗;窗子又是指隔绝自己生活与他人世界的象征。
有的人坐在窗子里面,有的人行走在窗子外面,而一扇窗子隔绝出来的,是两个截然不同的世界,窗外的人固然不了解窗里的人,窗里的人,也永远不能了解窗外的人。
6.你、我的代表了两种不同的人生视角,观看自己生活的视角和观看他人生活的视角。窗外是劳作、奔波、挣扎、穷苦,窗内是奢侈、悠闲、烦闷、无聊。这是两个世界,两种生活。蕴含着作者的态度:窗里窗外是两个世界,窗外的人无法理解窗内,窗内的人也无法走进窗外,我们只能以一个旁观者的角度对待世界,不要以为自己真正的解了什么而私下满足,“天知道那是罪过”。
['1. B']

这段代码主要执行以下操作:

  1. 提取数据

    • 从一个名为 df 的DataFrame中获取第61行(因为索引从0开始,所以索引为60的行实际上是第61行)的“答案”列的内容。这一行的内容被赋值给变量 second_row_option_content
  2. 显示提取的数据

    • 使用 print(second_row_option_content) 输出变量 second_row_option_content 的值,即显示第61行的“答案”列内容。
  3. 调用函数处理答案

    • 调用 chinese_multiple_choice_answers(second_row_option_content) 函数,传入刚才提取的答案文本。该函数的目的是解析文本中的答案,并返回选择题答案的列表,格式化为题号和答案的组合,例如 [“1. A”, “2. B”]。

这样,你可以直接看到第61行的答案内容,并得到这些答案经过解析后的格式化输出。

df['答案_processed'] = df['答案'].map(chinese_multiple_choice_answers)

2.4.4 构建Prompt

def get_prompt_cn(text):
    prompt = f'''
    你是⼀个⾼考选择题出题专家,你出的题有⼀定深度,你将根据阅读文本,出4道单项选择题,包含题目选项,以及对应的答案,注意:不⽤给出原文,每道题由1个问题和4个选项组成,仅存在1个正确答案,请严格按照要求执行。 阅读文本主要是中文,你出的题目需要满足以下要点,紧扣文章内容且题干和答案为中文:
    
    ### 回答要求
    (1)理解文中重要概念的含义
    (2)理解文中重要句子的含意
    (3)分析论点、论据和论证方法
    
    
    ### 阅读文本
    {text}
    '''
    
    return prompt   


def process_cn(df): 
    res_input = []
    res_output = []
    for id in range(len(df)):
        data_options = df.loc[id, '选项']
        data_answers = df.loc[id,'答案']
        data_prompt = df.loc[id,'阅读文本']
        data_options = chinese_multiple_choice_questions(data_options)
        data_answers = chinese_multiple_choice_answers(data_answers)
        data_prompt = get_prompt_cn(data_prompt)
        # print(data_options)
        # print(data_answers)
        
        if(len(data_answers)==len(data_options)):
            res = ''
            for id_,question in enumerate(data_options):
                res += f'''
{question['question']}?
                '''+'\n'
                for choise in question['choices']:
                    res = res+ choise[0] + choise[1]+ '\n'
                res = res + '答案:' + str(data_answers[id_].split('.')[-1])  + '\n'
            res_output.append(res)
            res_input.append(data_prompt)
        # break
    return res_input,res_output
    
cn_input,cn_output = process_cn(df)
len(cn_input)
58

这段代码定义了两个函数,并使用它们来处理一个DataFrame df,目的是生成中文的高考选择题文本,并将题目与答案格式化输出。下面详细解释代码的各个部分:

  1. 函数 get_prompt_cn

    • 功能:基于给定的阅读文本生成一个格式化的高考选择题指令。
    • 输入:阅读文本 text
    • 输出:返回一个包含具体指令和阅读文本的字符串,指导出题专家按要求出题。
  2. 函数 process_cn

    • 处理数据:遍历DataFrame df 的每一行,提取相应的阅读文本、选项和答案数据。
    • 调用其他函数
      • 使用 chinese_multiple_choice_questions 解析选项。
      • 使用 chinese_multiple_choice_answers 解析答案。
      • 使用 get_prompt_cn 生成针对每个阅读文本的出题指令。
    • 数据匹配和输出格式化
      • 检查每组题目的选项数和答案数是否匹配。
      • 格式化输出每道题的题干、选项和答案,并将它们组织成一整块文本。
    • 返回结果:返回两个列表,res_input 包含每个问题的出题指令,res_output 包含每个问题的题目和答案。
  3. 数据处理流程

    • 代码中的 for 循环遍历DataFrame的每一行数据。
    • 对于每一行,它提取阅读文本、选项和答案,然后调用相应的函数进行处理。
    • 如果选项和答案的数量相等,它将题目和答案格式化为字符串,并添加到输出列表中。
  4. 最终执行

    • 调用 process_cn(df),通过这个函数处理 df 中的数据。
    • cn_inputcn_output 分别存储了每个问题的指令和格式化的题目与答案。
    • 使用 len(cn_input) 来检查生成的问题数量。

这个脚本主要用于自动化生成和格式化中文选择题,适用于教育和测试准备领域,可以大幅提高出题效率和准确性。

2.5 英文问答数据制作

# coding~

import pandas as pd

# 读取Excel文件
df = pd.read_excel('训练集-英语.xlsx')
df = df.replace('.', '.', regex=True).replace('А.', 'A.', regex=True).replace('В.', 'B.', regex=True).replace('С.', 'C.', regex=True).replace('D.', 'D.', regex=True)
# df = df.replace('(', '(', regex=True)

# 读取第二行(即第三行)“选项”列的内容
second_row_option_content = df.loc[0, '选项']

# 显示第二行“选项”列的内容
print(second_row_option_content)
21. What is an advantage of MacBike?
A. It gives children a discount.
B. It of offers many types of bikes.
C. It organizes free cycle tours.
D. It has over 2,500 rental shops.
22. How much do you pay for renting a bike with hand brake and three gears for two days?
A. €15.75.
B. €19.50.
C. €22.75.
D. €29.50.
23. Where does the guided city tour start?
A. The Gooyer, Windmill.
C. Heineken Brewery.
B. The Skinny Bridge.
D. D.m Square.
def remove_whitespace_and_newlines(input_string):
    # 使用str.replace()方法删除空格和换行符
    result = input_string.replace(" ", "").replace("\n", "").replace(".", "")
    return result
import re

# 示例文本
text = """
32. B. The underlying logic of the effect.                                                   33.D. estimates were not fully independent.
34.C. The discussion process.            35.D. Approving.
"""
def get_answers(text):
    text = remove_whitespace_and_newlines(text)
    # 正则表达式模式
    pattern = re.compile(r'(\d)\s*([A-D])')

    # 查找所有匹配项
    matches = pattern.findall(text)
    res = []
    # 打印结果
    for match in matches:
        number_dot, first_letter = match
        res.append(first_letter)
    return res

# 示例输入
input_string = "28. A. It is simple and plain.              29. D. Influential.                                30. D.33%.                                             31. B. Male chefs on TV programmes."
res = get_answers(input_string)
print(res)
['A', 'D', 'D', 'B']
import re

# 示例文本
text = second_row_option_content

def get_questions(text):
    text = text.replace('\n', '  ')+'  '
    # print(text)
    # 正则表达式模式
    pattern = re.compile(r'(\d+\..*?)(A\..*?\s{2})([B-D]\..*?\s{2})([B-D]\..*?\s{2})(D\..*?\s{2})', re.DOTALL)

    # 查找所有匹配项
    matches = pattern.findall(text)

    # 存储结果的字典列表
    questions_dict_list = []

    # 打印结果
    for match in matches:
        question, option1, option2, option3, option4 = match
        pattern_question = re.compile(r'(\d+)\.(.*)')
        question_text = pattern_question.findall(question.strip())[0][1]
        
        # 提取选项字母和内容
        options = {option1[0]: option1, option2[0]: option2, option3[0]: option3, option4[0]: option4}
        
        question_dict = {
            'question': question_text,
            'options': {
                'A': options.get('A', '').strip(),
                'B': options.get('B', '').strip(),
                'C': options.get('C', '').strip(),
                'D': options.get('D', '').strip()
            }
        }
        questions_dict_list.append(question_dict)
    return questions_dict_list

# 调用函数并打印结果
questions = get_questions(text)
for q in questions:
    print(q)
{'question': ' What is an advantage of MacBike?', 'options': {'A': 'A. It gives children a discount.', 'B': 'B. It of offers many types of bikes.', 'C': 'C. It organizes free cycle tours.', 'D': 'D. It has over 2,500 rental shops.'}}
{'question': ' How much do you pay for renting a bike with hand brake and three gears for two days?', 'options': {'A': 'A. €15.75.', 'B': 'B. €19.50.', 'C': 'C. €22.75.', 'D': 'D. €29.50.'}}
{'question': ' Where does the guided city tour start?', 'options': {'A': 'A. The Gooyer, Windmill.', 'B': 'B. The Skinny Bridge.', 'C': 'C. Heineken Brewery.', 'D': 'D. D.m Square.'}}
def get_prompt_en(text):
    prompt = f'''
    你是⼀个⾼考选择题出题专家,你出的题有⼀定深度,你将根据阅读文本,出4道单项选择题,包含题目选项,以及对应的答案,注意:不⽤给出原文,每道题由1个问题和4个选项组成,仅存在1个正确答案,请严格按照要求执行。
The reading text is mainly in English. The questions and answers you raised need to be completed in English for at least the following points:
    
    ### 回答要求
    (1)Understanding the main idea of the main idea.
    (2)Understand the specific information in the text.
    (3)infering the meaning of words and phrases from the context
    
    
    ### 阅读文本
    {text}
    '''
    
    return prompt   


def process_en(df): 
    res_input = []
    res_output = []
    for id in range(len(df)):
        data_options = df.loc[id, '选项']
        data_answers = df.loc[id,'答案']
        data_prompt = df.loc[id,'阅读文本']
        data_options = get_questions(data_options)
        data_answers = get_answers(data_answers)
        data_prompt = get_prompt_en(data_prompt)
        # print(data_options)
        # print(data_answers)

        if(len(data_answers)==len(data_options)):
            res = ''
            for id,question in enumerate(data_options):
                res += f'''
                {id+1}.{question['question']}
                {question['options']['A']}
                {question['options']['B']}
                {question['options']['C']}
                {question['options']['D']}
                answer:{data_answers[id]}
                '''+'\n'
            res_output.append(res)
            res_input.append(data_prompt)
    return res_input,res_output
    # break

en_input,en_output = process_en(df)

2.6 数据保存

# 将两个列表转换为DataFrame
df_new = pd.DataFrame({'input': cn_input+cn_input[:30]+en_input+en_input[:20], 'output': cn_output+cn_output[:30]+en_output+en_output[:20]})

df_new

在这里插入图片描述

import json


# 打开一个文件用于写入 JSONL,并设置编码为 UTF-8
with open('output.jsonl', 'w', encoding='utf-8') as f:
    # 遍历每一行并将其转换为 JSON
    for index, row in df_new.iterrows():
        row_dict = row.to_dict()
        row_json = json.dumps(row_dict, ensure_ascii=False,)
        # 将 JSON 字符串写入文件,并添加换行符
        f.write(row_json + '\n')

# 打印确认信息
print("JSONL 文件已生成")

得到用于模型微调的output.jsonl文件

3. 大模型微调

参考链接:https://training.xfyun.cn/dataset/datasetIndex

3.1 微调相关知识

3.1.1 大模型微调简介

大模型微调是自然语言处理(NLP)中一种重要的技术,它使得通用的预训练语言模型如GPT-3、BERT等能够针对特定任务进行优化。微调的本质是在保持大部分预训练知识的基础上,通过在特定任务的数据集上进行额外训练,使模型更好地适应特定的应用需求。

现有的微调方法大体可以分为以下几种:

  1. 全模型微调:这是最直接的方法,涉及在特定任务的数据集上调整模型的所有权重。这种方法通常能够达到较好的性能,但需要较多的训练数据来避免过拟合。

  2. 层次微调:在这种方法中,只有模型的部分层(通常是顶层或接近输出的层)会被微调。这样可以减少计算量,同时保留更多的预训练知识。

  3. 适应性微调(Adapter Tuning):适应性微调涉及向预训练模型中添加小型的可训练层(称为适配器),而原始的模型权重保持不变。这种方法既可以节省训练资源,又能有效避免过拟合。

3.1.2 扩充数据集操作

在NLP任务中,尤其是在微调大模型时,数据集的质量和多样性对最终性能有显著影响。以下是常见的数据集扩充方法:

  1. 数据增强:通过对现有数据进行修改来创建新数据。常见的技术包括同义词替换、回译(使用机器翻译将文本翻译成一种语言再翻译回来)和随机删除。

  2. 外部数据集融合:将相关的外部数据集融入到训练集中。这要求外部数据与任务高度相关,且风格和质量与现有数据相匹配。

  3. 伪标签技术:利用模型自身生成的预测来标注未标记的数据,然后将这些数据用于进一步训练。这种方法可以在数据标注资源有限的情况下扩充数据集。

3.1.3 调整Prompt

Prompt工程是大模型尤其是如GPT这类生成模型中的关键技术。通过精心设计的prompt,可以显著提高模型在特定任务上的表现。以下是几种常见的Prompt设计方法:

  1. 模板式Prompt:构建固定的文本模板,如“根据以下内容,问答式回复:[文本]”,这种方式简单直接,易于实现。

  2. 探索式Prompt:通过尝试不同的提问方式、语气和详细程度,找到最优的prompt。这种方法需要大量的实验和调整。

  3. 动态Prompt:根据输入文本的上下文动态调整prompt。例如,根据文章的主题或复杂度调整问题的形式和难度。

  4. 链式Prompt:设计一系列的prompt,将模型的输出作为下一个prompt的输入,形成链式反馈。这种方法特别适用于需要多步推理的任务。

3.1.4 总结

大模型微调是将预训练的通用模型适配到特定任务的有效方法。通过扩充数据集、调整模型架构和优化prompt,可以显著提高模型在特定任务上的表现。这些技术不仅增强了模型的应用范围,也提高了其在实际应用中的准确性和灵活性。

3.2 模型微调

参考链接:https://linklearner.com/activity/14/12/26

3.2.1 数据上传

将第二章得到用于模型微调的output.jsonl文件进行上传,并用在线模型进行微调。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.2 模型训练

在这里插入图片描述
一般会训练30分钟左右(目前平台推理时间过长,可能实际训练时间会更久一些有的甚至3-4h),如果排队的话可能会久一些。

3.2.3 模型发布

在这里插入图片描述
在这里插入图片描述
注意:如果大家没有应用请到 https://console.xfyun.cn/app/myapp 点击创建创建一个。
在这里插入图片描述

3.2.4 模型测试

在这里插入图片描述
请大家正确输入:

  SPARKAI_APP_ID = ''
  SPARKAI_API_SECRET = ''
  SPARKAI_API_KEY = ''
  serviceld=
  resourceld=

在这里插入图片描述
运行notebook,模型输出为:
在这里插入图片描述

3.2.5 提交文件

链接:http://challenge.xfyun.cn/topic/info?type=question-bank-construction&option=tjjg

点击提交结果后,需要在https://training.xfyun.cn/刚才的微调页面拿一下resourceid
在这里插入图片描述
接着拿好我们的prompt:
中文部分

    (1)理解文中重要概念的含义
    (2)理解文中重要句子的含意
    (3)分析论点、论据和论证方法

英文部分

    (1)Understanding the main idea of the main idea.
    (2)Understand the specific information in the text.
    (3)infering the meaning of words and phrases from the context

在这里插入图片描述

3.2.6 分数

在这里插入图片描述

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值