自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

微調(diào)谷歌開源Gemini Flash模型實(shí)現(xiàn)PII脫敏實(shí)戰(zhàn) 原創(chuàng)

發(fā)布于 2024-10-9 08:22
瀏覽
0收藏

本文將通過具體的實(shí)戰(zhàn)代碼示例來探索谷歌開源Gemini Flash模型的學(xué)習(xí)曲線和采樣效率。

在大多數(shù)常見的機(jī)器學(xué)習(xí)和自然語言處理中,實(shí)現(xiàn)最佳性能通常需要在用于訓(xùn)練的數(shù)據(jù)量和由此產(chǎn)生的模型準(zhǔn)確性之間進(jìn)行權(quán)衡。本文中,我們將以PII(個(gè)人識(shí)別信息)脫敏算法數(shù)據(jù)集為例,探討使用微調(diào)谷歌Gemini Flash模型的情況下樣本效率的概念。我們將研究隨著樣本數(shù)量的增加而進(jìn)行的微調(diào)如何影響調(diào)整后的模型的功能。

何謂樣本效率,為什么它很重要?

樣本效率(Sample efficiency)是指模型在有限的訓(xùn)練數(shù)據(jù)量下實(shí)現(xiàn)高精度的能力。這是機(jī)器學(xué)習(xí)開發(fā)的一個(gè)關(guān)鍵方面,尤其是在處理大型標(biāo)記數(shù)據(jù)集可能稀缺或獲取成本高昂的任務(wù)或領(lǐng)域的情況下。一個(gè)樣本高效的模型可以從更少的樣本中有效地學(xué)習(xí),減少與數(shù)據(jù)收集和訓(xùn)練相關(guān)的時(shí)間、成本和精力。LLM被證明是非常有樣本效率的,甚至能夠在很少的樣本情況下進(jìn)行情境學(xué)習(xí),也能夠顯著提高性能。本文的主要目標(biāo)是以谷歌開源的Gemini Flash模型為例來探討這方面的問題。我們將在不同設(shè)置條件下評(píng)估此LLM模型,然后繪制學(xué)習(xí)曲線,以便更直觀地了解訓(xùn)練數(shù)據(jù)量是如何影響性能的。

微調(diào)谷歌開源Gemini Flash模型實(shí)現(xiàn)PII脫敏實(shí)戰(zhàn)-AI.x社區(qū)

顯示訓(xùn)練得分和交叉驗(yàn)證得分的學(xué)習(xí)曲線示例(來源:維基百科)

微調(diào)Gemini Flash模型實(shí)現(xiàn)PII脫敏實(shí)戰(zhàn)

為了展示樣本效率的影響,我們將進(jìn)行一項(xiàng)實(shí)驗(yàn),重點(diǎn)是微調(diào)Gemini Flash模型,從而應(yīng)用于個(gè)人識(shí)別信息脫敏。我們將使用Hugging Face公司的公開個(gè)人識(shí)別信息脫敏數(shù)據(jù)集,并評(píng)估模型在不同微調(diào)場(chǎng)景下的性能:

  • 零樣本設(shè)置:評(píng)估預(yù)先訓(xùn)練的Gemini Flash模型,無需任何微調(diào)。
  • 小樣本設(shè)置(3-shot):在要求模型個(gè)人識(shí)別信息脫敏新文本之前,為模型提供3個(gè)樣本。
  • 使用50|200|800|3200|6400個(gè)樣本進(jìn)行微調(diào):使用從小到大的“PII/Masked(個(gè)人識(shí)別信息明文/個(gè)人識(shí)別信息密文)”對(duì)數(shù)據(jù)集對(duì)模型進(jìn)行微調(diào)。

對(duì)于每種設(shè)置,我們將在200個(gè)句子的固定測(cè)試集上評(píng)估模型的性能,使用BLEU(bilingual evaluation understudy:雙語替換測(cè)評(píng))指標(biāo)來衡量生成的脫敏文本的質(zhì)量。該指標(biāo)能夠評(píng)估模型輸出和脫敏句子之間的重疊性,提供脫敏準(zhǔn)確性的定量衡量。

實(shí)驗(yàn)限制

這個(gè)小實(shí)驗(yàn)的結(jié)果可能不會(huì)直接推廣到其他使用場(chǎng)景或數(shù)據(jù)集情況下。另外,微調(diào)的最佳數(shù)據(jù)量取決于各種因素,包括任務(wù)的性質(zhì)和復(fù)雜性、數(shù)據(jù)的質(zhì)量以及基礎(chǔ)模型的具體特征等。

我的建議是,你可以從這篇文章提供的代碼中獲得一些靈感,或者:

  • 如果你已經(jīng)有了數(shù)據(jù),可以直接將其應(yīng)用于你的使用場(chǎng)景,這樣你就可以看到你的訓(xùn)練曲線是否變慢了(這意味著,你的收益正在顯著下降)
  • 或者,如果你沒有數(shù)據(jù)的話,那么可以為你所遇到的同類問題(分類、命名實(shí)體識(shí)別、摘要)和類似的難度級(jí)別找到一個(gè)數(shù)據(jù)集。這樣的話,你就可以通過繪制學(xué)習(xí)曲線來了解你自己的任務(wù)需要多少數(shù)據(jù)。

實(shí)驗(yàn)數(shù)據(jù)

我們將使用在Huggingface上共享的PII(個(gè)人身份信息)掩蔽數(shù)據(jù)集。

該數(shù)據(jù)集中包含兩對(duì)文本,一對(duì)是帶有脫敏信息的原始文本,另一對(duì)文本隱藏了所有原始個(gè)人身份信息。

舉例

輸入:

A student’s assessment was found on device bearing IMEI: 06–184755–866851–3. The document falls under the various topics discussed in our Optimization curriculum. Can you please collect it?

目標(biāo):

A student’s assessment was found on device bearing IMEI: [PHONEIMEI]. The document falls under the various topics discussed in our [JOBAREA] curriculum. Can you please collect it?

注意,上面數(shù)據(jù)是經(jīng)過合成處理的;所以,這里實(shí)際上沒有共享真正的個(gè)人身份信息。

我們的目標(biāo)是建立從源文本到目標(biāo)文本的映射,以自動(dòng)隱藏所有個(gè)人身份信息。

數(shù)據(jù)許可:

??https://huggingface.co/datasets/ai4privacy/pii-masking-200k/blob/main/license.md。??

編程實(shí)現(xiàn)

我們將提供一些編程代碼,以方便加速此實(shí)驗(yàn)進(jìn)程。編碼中,我們將利用Hugging Face數(shù)據(jù)集庫加載個(gè)人身份信息脫敏數(shù)據(jù)集,并利用google.generativeai庫與Gemini Flash交互,還將利用evaluate庫來計(jì)算BLEU(雙語替換測(cè)評(píng))分?jǐn)?shù)。

pip install transformers datasets evaluate google-generativeai python-dotenv sacrebleu

此代碼段實(shí)現(xiàn)安裝項(xiàng)目所需的庫,包括:

  • 數(shù)據(jù)集:便于從Hugging Face加載和處理數(shù)據(jù)集。
  • evaluate庫:允許使用SacreBLEU等評(píng)估指標(biāo)。
  • google-generativeai:允許與谷歌的Gemini API交互。

首先,我們進(jìn)行數(shù)據(jù)加載和拆分:

#導(dǎo)入必需的庫
from datasets import load_dataset
from google.generativeai.types import HarmCategory, HarmBlockThreshold
# Define GOOGLE_API_KEY as a global variable
# 加載和分割數(shù)據(jù)集函數(shù)
def load_data(train_size: int, test_size: int):
    """
    加載pii-masking-200k數(shù)據(jù)集并把它拆分成訓(xùn)練與測(cè)試兩種類型。
    參數(shù):
        train_size: 訓(xùn)練數(shù)據(jù)集的大小
        test_size: 測(cè)試數(shù)據(jù)集的大小
    返回:
       一個(gè)包含訓(xùn)練數(shù)據(jù)集和測(cè)試數(shù)據(jù)集的元組。
    """
    dataset = load_dataset("ai4privacy/pii-masking-200k")
    dataset = dataset["train"].train_test_split(test_size=test_size, seed=42)
    train_d = dataset["train"].select(range(train_size))
    test_d = dataset["test"]
    return train_d, test_d

接下來,我們嘗試為該任務(wù)提示零樣本。這意味著,我們向LLM解釋任務(wù),并要求它從原始文本中生成個(gè)人身份信息脫敏數(shù)據(jù)。這是通過使用一個(gè)列出所有需要脫敏標(biāo)簽的提示來完成的。

我們還將LLM API的調(diào)用并行化,以稍微加快速度。

最后,我們使用BLEU評(píng)分進(jìn)行評(píng)估。它是一種基于精度的度量方案,通常用于機(jī)器翻譯,將模型輸出與參考句子進(jìn)行比較。雖然這種方法存在一定局限性,但卻易于應(yīng)用,適用于像我們手頭這樣的文本到文本任務(wù)。

import google.generativeai as genai
from google.generativeai.types.content_types import ContentDict
from google.generativeai.types import HarmCategory, HarmBlockThreshold

from concurrent.futures import ThreadPoolExecutor
import evaluate

safety_settings = {
    HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_NONE,
    HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE,
    HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_NONE,
    HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
}
SYS_PROMPT = (
    "Substitute all PII in this text for a generic label like [FIRSTNAME] (Between square brackets)\n"
    "Labels to substitute are PREFIX, FIRSTNAME, LASTNAME, DATE, TIME, "
    "PHONEIMEI, USERNAME, GENDER, CITY, STATE, URL, JOBAREA, EMAIL, JOBTYPE, "
    "COMPANYNAME, JOBTITLE, STREET, SECONDARYADDRESS, COUNTY, AGE, USERAGENT, "
    "ACCOUNTNAME, ACCOUNTNUMBER, CURRENCYSYMBOL, AMOUNT, CREDITCARDISSUER, "
    "CREDITCARDNUMBER, CREDITCARDCVV, PHONENUMBER, SEX, IP, ETHEREUMADDRESS, "
    "BITCOINADDRESS, MIDDLENAME, IBAN, VEHICLEVRM, DOB, PIN, CURRENCY, "
    "PASSWORD, CURRENCYNAME, LITECOINADDRESS, CURRENCYCODE, BUILDINGNUMBER, "
    "ORDINALDIRECTION, MASKEDNUMBER, ZIPCODE, BIC, IPV4, IPV6, MAC, "
    "NEARBYGPSCOORDINATE, VEHICLEVIN, EYECOLOR, HEIGHT, SSN, language"
)
#計(jì)算零樣本設(shè)置的函數(shù)
def evaluate_zero_shot(train_data, test_data, model_name="gemini-1.5-flash"):
    """
    評(píng)估該模型的零樣本性能。
    參數(shù):
        train_data: 訓(xùn)練數(shù)據(jù)集(不用于零樣本情況)。
        test_data: 測(cè)試數(shù)據(jù)集。
        model_name: 要使用的模型的名稱。
    返回值 :
        零樣本設(shè)置的SacreBLEU分?jǐn)?shù)
    """
    model = genai.GenerativeModel(model_name)
    def map_zero_shot(text):
        messages = [
            ContentDict(
                role="user",
                parts=[f"{SYS_PROMPT}\nText: {text}"],
            ),
        ]
        response = model.generate_content(messages, safety_settings=safety_settings)
        try:
            return response.text
        except ValueError:
            print(response)
            return ""
    with ThreadPoolExecutor(max_workers=4) as executor:
        predictions = list(
            executor.map(
                map_zero_shot,
                [example["source_text"] for example in test_data],
            )
        )
    references = [[example["target_text"]] for example in test_data]
    sacrebleu = evaluate.load("sacrebleu")
    sacrebleu_results = sacrebleu.compute(
        predictions=predictions, references=references
    )
    print(f"Zero-shot SacreBLEU score: {sacrebleu_results['score']}")
    return sacrebleu_results["score"]

現(xiàn)在,讓我們進(jìn)一步探討有關(guān)提示的問題。除了向LLM解釋任務(wù)外,我們還將向它展示三個(gè)我們期望它做什么的例子。這種技巧通常有助于提高性能。

# 評(píng)估小樣本設(shè)置的函數(shù)
def evaluate_few_shot(train_data, test_data, model_name="gemini-1.5-flash"):
    """
    評(píng)估模型的小樣本性能
    參數(shù):
        train_data: 訓(xùn)練數(shù)據(jù)集
        test_data: 測(cè)試數(shù)據(jù)集
        model_name: 要使用的模型的名稱。
    返回值:
        小樣本設(shè)置的SacreBLEU分?jǐn)?shù)
    """
    model = genai.GenerativeModel(model_name)
    def map_few_shot(text, examples):
        messages = [
            ContentDict(
                role="user",
                parts=[SYS_PROMPT],
            )
        ]
        for example in examples:
            messages.append(
                ContentDict(role="user", parts=[f"Text: {example['source_text']}"]),
            )
            messages.append(
                ContentDict(role="model", parts=[f"{example['target_text']}"])
            )
        messages.append(ContentDict(role="user", parts=[f"Text: {text}"]))
        response = model.generate_content(messages, safety_settings=safety_settings)
        try:
            return response.text
        except ValueError:
            print(response)
            return ""
    few_shot_examples = train_data.select(range(3))
    with ThreadPoolExecutor(max_workers=4) as executor:
        predictions = list(
            executor.map(
                lambda example: map_few_shot(example["source_text"], few_shot_examples),
                test_data,
            )
        )
    references = [[example["target_text"]] for example in test_data]
    sacrebleu = evaluate.load("sacrebleu")
    sacrebleu_results = sacrebleu.compute(
        predictions=predictions, references=references
    )
    print(f"3-shot SacreBLEU score: {sacrebleu_results['score']}")
    return sacrebleu_results["score"]

最后,我們來嘗試一下使用微調(diào)方案。在這里,我們只使用Gemini API的托管服務(wù)。它現(xiàn)在是免費(fèi)的,所以不妨使用一下。注意,我們將使用越來越多的數(shù)據(jù),并比較每種數(shù)據(jù)的性能。

運(yùn)行調(diào)優(yōu)任務(wù)再簡(jiǎn)單不過了:我們只需使用genai.create_tuned_model函數(shù)來處理數(shù)據(jù)、迭代次數(shù)、學(xué)習(xí)率和參數(shù)。

訓(xùn)練任務(wù)是異步的,這意味著我們不必等待程序的運(yùn)行結(jié)束。不過,程序的執(zhí)行要排隊(duì),通常在24小時(shí)內(nèi)完成。

def finetune(train_data, finetune_size, model_name="gemini-1.5-flash"):
    """
    調(diào)優(yōu)模型

    參數(shù):
        train_data: 訓(xùn)練數(shù)據(jù)集。
        finetune_size:用于微調(diào)的樣本數(shù)量。
        model_name: 要用于進(jìn)行微調(diào)的基本模型的名稱。
    返回值:
        已調(diào)優(yōu)的模型的名稱。
    """
    base_model = f"models/{model_name}-001-tuning"
    tuning_data = [
        {
            "text_input": f"{SYS_PROMPT}\nText: {example['source_text']}",
            "output": example["target_text"],
        }
        for example in train_data.select(range(finetune_size))
    ]
    print(len(tuning_data))
    operation = genai.create_tuned_model(
        display_name=f"tuned-{finetune_size}",
        source_model=base_model,
        epoch_count=2,
        batch_size=4,
        learning_rate=0.0001,
        training_data=tuning_data,
    )

你可以使用以下代碼片段來檢查一下調(diào)優(yōu)任務(wù)的狀態(tài):

import google.generativeai as genai

for model_info in genai.list_tuned_models():
    print(model_info.name)
    print(model_info)

實(shí)驗(yàn)結(jié)果對(duì)比分析

微調(diào)谷歌開源Gemini Flash模型實(shí)現(xiàn)PII脫敏實(shí)戰(zhàn)-AI.x社區(qū)

構(gòu)建PII數(shù)據(jù)脫敏函數(shù)時(shí)不同設(shè)置方案結(jié)果比較

容易看出,PII數(shù)據(jù)脫敏算法通過添加更多用于微調(diào)的訓(xùn)練數(shù)據(jù)提高了性能。

零樣本和小樣本情況

由上圖可知,零樣本方法獲得了83.85的令人尊敬的BLEU分?jǐn)?shù)。這表明,即使沒有任何訓(xùn)練樣本,模型也會(huì)對(duì)任務(wù)有一些基本的理解。然而,實(shí)驗(yàn)中只提供三個(gè)樣本(3-shot)就可以將分?jǐn)?shù)提高到87.59,這說明了即使是有限的樣本情況下,這些樣本在LLM情境學(xué)習(xí)中也是非常有效的。

微調(diào)情況

實(shí)驗(yàn)一開始,我們使用50個(gè)樣本的小數(shù)據(jù)集進(jìn)行微調(diào),得出的BLEU得分為86.38,略低于3-shot方法。然而,隨著訓(xùn)練數(shù)據(jù)的增加,性能顯著提高。在使用了200個(gè)樣本的情況下,BLEU得分躍升至90.97,而在使用了800個(gè)樣本時(shí)則達(dá)到了94.30。當(dāng)使用最大數(shù)量達(dá)到6400個(gè)樣本測(cè)試的情況下達(dá)到最高BLEU分?jǐn)?shù)97.52。

結(jié)論

我們最后得到的基本結(jié)論是:一切都在意料之中,隨著數(shù)據(jù)的增加,性能也會(huì)提高。雖然Gemini Flash模型的零樣本和小樣本功能令人印象深刻,證明了其具有推廣到新任務(wù)的能力,但是使用足夠大的數(shù)據(jù)進(jìn)行微調(diào)時(shí)也會(huì)顯著提高其準(zhǔn)確性。這里唯一出乎意料的是,如果訓(xùn)練數(shù)據(jù)的數(shù)量太少或質(zhì)量太低,那么小樣本提示結(jié)果的準(zhǔn)確率有時(shí)會(huì)勝過經(jīng)過微調(diào)后的準(zhǔn)確率。

總之,我們可以得到如下幾條關(guān)鍵結(jié)論:

  • 要實(shí)現(xiàn)高性能目標(biāo),微調(diào)可能是必要的:即使少量的微調(diào)數(shù)據(jù)也比零樣本和小樣本方法產(chǎn)生巨大的改進(jìn)。
  • 更多的數(shù)據(jù)通常會(huì)帶來更好的結(jié)果:隨著微調(diào)數(shù)據(jù)集大小的增加,調(diào)優(yōu)后的模型的準(zhǔn)確脫敏個(gè)人身份信息的能力也會(huì)提高,如上圖中BLEU分?jǐn)?shù)的上升所表明的。
  • 收益遞減:雖然更多的數(shù)據(jù)通常會(huì)產(chǎn)生更好的數(shù)據(jù)結(jié)果,但也可能會(huì)出現(xiàn)性能增長(zhǎng)開始趨于平穩(wěn)的時(shí)刻。確定這一點(diǎn)可以幫助我們更好地權(quán)衡標(biāo)簽預(yù)算和調(diào)整模型質(zhì)量之間的權(quán)衡。

還需要說明的是,在我們的例子中,穩(wěn)定期從3200個(gè)樣本開始,任何高于這個(gè)水平的樣本都會(huì)產(chǎn)生正的但遞減的回報(bào)。

譯者介紹

朱先忠,51CTO社區(qū)編輯,51CTO專家博客、講師,濰坊一所高校計(jì)算機(jī)教師,自由編程界老兵一枚。

原文標(biāo)題:?How Much Data Do You Need to Fine-Tune Gemini???,作者:Youness Mansar

?著作權(quán)歸作者所有,如需轉(zhuǎn)載,請(qǐng)注明出處,否則將追究法律責(zé)任
收藏
回復(fù)
舉報(bào)
回復(fù)
相關(guān)推薦