分享

垂类模型自制数据集的尝试,附实跑代码!

 奥莉芙小异 2024-05-10 发布于江西

终于!跑通了!

我们一直在做垂类模型自制数据集的尝试,

在网络教程的基础上,我写了一个脚本:

这份代码实现:读取专业文件pdf开始, 首先判断是否是图像pdf, 如果是图像pdf则进行ocr, 如果不是则直接提取文本到数据集,再用bonito进行处理。



图片

这,很有价值

指令是给 LLM(如 Llama、GPT-4 等)的文本或提示。

它指示模型做出特定类型的回答。

通过指令,人们可以引导讨论,确保模型的回答是相关的、有帮助的,并且符合用户的需求。

创建清晰准确的指令对于实现预期结果非常重要。

图片

Bonito 是一个用于条件任务生成的开源模型。它可用于创建合成指令调整数据集,使大型语言模型适应用户的专用私人数据。

图片

Bonito 工作流程。源代码 学习生成指令调整数据集以进行零点任务适配

Bonito 开发所依据的研究论文说明了如何有效地利用 Bonito 来调整预训练和指令调整模型,使其适用于各种任务,而无需任何文本注释。

模型本身是在 mistralai/Mistral-7B-v0.1 的基础上,利用包含 165 万个示例的新大型数据集进行微调的。

Bonito 还支持多种任务类型,包括**多选题回答、是非题回答、自然语言推理、主题分类等**。

使用 Bonito 模型的最简单方法是通过**基于转换器和 vllm 库的软件包**。

图片

以下是我的代码,基于python语言,

期间多次使用kimi进行开发和排错,在自己的环境中调试。

import sysimport fitz  # PyMuPDFimport paddleocr as ocrimport spacyimport refrom datasets import Dataset, Features, Value, load_datasetimport osfrom PIL import Imageimport ioimport numpy as npfrom bonito import Bonitofrom vllm import SamplingParams# 配置PaddleOCR,指定中文简体模型ocr_system = ocr.PaddleOCR(use_angle_cls=True, lang='ch')# 确保已经安装并正确加载Spacy英文和中文模型try:    nlp_en = spacy.load('en_core_web_sm')    nlp_zh = spacy.load('zh_core_web_sm')except OSError:    print('Spacy language models not found. Please download them with:')    print('python -m spacy download en_core_web_sm')    print('python -m spacy download zh_core_web_sm')    sys.exit(1)def is_text_pdf(pdf_path):    try:        doc = fitz.open(pdf_path)        text = ''        for page in doc:            text += page.get_text()        doc.close()        if text.strip():  # 如果提取的文本不为空            return True    except Exception as e:        print(f'Error during direct text extraction: {e}')    return Falsedef detect_language(text):    # 使用Spacy进行语言检测    if nlp_zh(text).lang_ == 'zh':        return 'chi_sim'    elif nlp_en(text).lang_ == 'en':        return 'eng'    else:        return Nonedef detect_language_with_ocr(pdf_path, check_pages=5):    text_list = []    for i in range(check_pages):        try:            doc = fitz.open(pdf_path)            page = doc[i]            pm = page.get_pixmap()            img = Image.open(io.BytesIO(pm.tobytes('png', 'big')))            text = ocr_system.ocr(img, cls=True)            print(f'OCR for page {i}: {text}')            text_list.append(''.join([line[-1] for line in text if len(line) == 3]))            doc.close()        except Exception as e:            print(f'Error during OCR for page {i+1}: {e}')            # 尝试继续处理其他页面,而不是直接返回None           continue    # 合并所有页面的文本并进行语言检测    full_text = ' '.join(text_list)    return detect_language(full_text)def extract_text_from_pdf(pdf_path, is_ocr_needed):    doc = fitz.open(pdf_path)    text = ''  # 确保text在函数内定义,并且在整个函数范围内可访问    if not is_ocr_needed:        for page in doc:            try:                text += page.get_text()            except Exception as e:                print(f'Error extracting text from page: {e}')    else:        for i, page in enumerate(doc):            try:                pm = page.get_pixmap()                img = Image.open(io.BytesIO(pm.tobytes('png', 'big')))                img_array = np.array(img)                result = ocr_system.ocr(img_array, cls=True)                print(f'OCR result for page {i}: {result}')                text_page = ''                for block in result[0]:  # 遍历每个区块            # 每个区块的最后一个元素是一个包含文本和置信度的元组                    text_data, _ = block[-1]                    text_page += text_data + '\n'  # 添加识别的文本和换行符                print(f'Text from page {i}: {text_page}')  # 打印当前页的文本                text += text_page  # 累加每一页的文本            except Exception as e:                print(f'Error during OCR on page {i+1}: {e}')    return text# 其他函数和代码保持不变def split_text_into_sentences(text):    # 使用正则表达式来识别句子结束的标点符号    # 这个正则表达式匹配了句号、问号或感叹号后面的空格或字符串的结尾    sentences = re.split(r'([。?!][\s\n]+)', text)    # 过滤掉空字符串,并合并连续的标点符号    sentences = [sentence.strip() for sentence in sentences if sentence]    print(f'sentences is : {sentences}')    return sentencesdef create_dataset(sentences, language='en'):    features = Features({        'sentence': Value('string'),        'language': Value('string')    })    return Dataset.from_dict({'sentence': sentences, 'language': [language] * len(sentences)}, features=features)def log_save_sample(sample, filename):    print(f'Saving sample: {sample} to file: {filename}')if __name__ == '__main__':    if len(sys.argv) != 3:        print('Usage: python script.py <pdf_path> <target_folder>')        sys.exit(1)    pdf_path = sys.argv[1]    target_folder = sys.argv[2]    # 判断PDF是文本类型还是图像类型    is_image_ocr = not is_text_pdf(pdf_path)    text = extract_text_from_pdf(pdf_path, is_image_ocr)    # 分割文本成句子    sentences = split_text_into_sentences(text)    # 检测语言(这里简化为使用OCR结果,实际应用中可以根据需要调整)    language = detect_language_with_ocr(pdf_path)    # 如果语言检测失败,设置默认语言为英文    if language is None:        print('Language detection failed, defaulting to English.')        language = 'eng'    dataset = create_dataset(sentences, language)    # 保存数据集到目标文件夹    os.makedirs(target_folder, exist_ok=True)    dataset.save_to_disk(target_folder)   # Initialize the Bonito model with adjusted parameters    bonito = Bonito(        'BatsResearch/bonito-v1',        gpu_memory_utilization=0.95,  # 增加GPU内存使用率        max_model_len=8192             # 减小模型的最大序列长度    )    # 设置采样参数    sampling_params = SamplingParams(        max_tokens=256,        top_p=0.95,        temperature=0.5,        n=1    )    # 使用 Bonito 生成合成问答任务    synthetic_dataset = bonito.generate_tasks(        dataset,        context_col='sentence',        task_type='qg',        sampling_params=sampling_params            )    # 保存合成数据集    synthetic_dataset.save_to_disk(os.path.join(target_folder, 'synthetic_dataset'))    print('Synthetic QA tasks generated by Bonito:')    print('Sample structure from the synthetic dataset:')    print(synthetic_dataset[0])  # 打印第一个样本的结构    print(f'Synthetic dataset has been saved to {os.path.join(target_folder, 'synthetic_dataset')}')

我还有从文件夹中读取所有pdf并处理的版本。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多