微調碾壓RAG?大模型意圖識別工程化實踐

阿里妹導讀
本文重點介紹大模型意圖識別能力在智慧電視核心鏈路中的落地過程和思考,對比了基礎模型、RAG 、以及7b模型微調三種方案的優缺點。
業務背景
今年是智慧電視行業在AI領域發力的元年,各廠家紛紛在自家電視OS中融入大模型能力,某國產品牌廠家更是提出了“可見即可說”的概念,希望藉助AI大模型強大的自然語言處理以及邏輯推理能力,在電視端提升使用者體驗以及創造新的業務增長場景。
透過下面這個影片可以先對整體互動有個概念:
使用者不再是簡單的發出系統指令,而是可能會問出更具有個性化需求的問題,比如以下幾個典型的問題:
介紹一下李白幫我播放兩個男人在天台決鬥的電影開啟右下角那個電視劇我想聽一個小朋友不好好吃飯就會肚子疼的故事深圳最近有哪些新聞?夏洛特煩惱這部電影中夏洛這個角色是不是沈騰演的?電影戰狼3的上映時間是什麼時候?
基於傳統NLP演算法的智慧電視互動痛點
智慧電視的概念其實在十幾年前就已經提出了,經過許多年的迭代已經初步具備人機智慧互動的能力,但是在傳統NLP技術體系下,有幾個問題導致體驗無法進一步提升,比如複雜語境下的意圖識別問題、上下文理解和多輪對話問題、泛化推理問題等。
比如使用者可能會問“我想看兩個男人在天台決鬥的電影”,此類問題在傳統NLP技術下是難以做到識別使用者是想看《無間道》的意圖的,而大模型強大的泛化推理能力可以很好的解決。
傳統NLP演算法在意圖識別場景的不足和侷限性

語言理解能力

  • 語義理解深度有限:傳統 NLP 演算法多依賴於基於規則的方法,像早期的專家系統,透過人工編寫大量規則來解析語義,但面對自然語言的高度靈活性,這些規則難以窮盡所有情況。以依存句法分析為例,在一些簡單句中它能識別出詞語間的語法關係,可一旦遇到複雜的長難句準確性大打折扣。
  • 上下文感知能力不足:像隱馬爾可夫模型(HMM)這樣傳統用於 NLP 的演算法,其在處理文字時大多聚焦於區域性的狀態轉移機率,對上下文連貫的長序列資訊整合能力欠佳。與之對比,大模型的Transformer 架構能讓模型同時關注輸入文字不同位置資訊,在多輪互動場景下表現較好。

互動體驗方面

  • 多輪對話效果不佳:傳統的對話管理系統常採用有限狀態機(FSM)演算法構建,它依據預設的狀態轉移規則驅動對話流程,在面對電視多輪對話場景有一定侷限性。
  • 靈活性和泛化性差:在智慧電視內容搜尋場景,使用者搜尋詞偏個性化時,如從 “科幻電影” 變為 “帶有科幻元素的冒險電影”,基於布林邏輯構建的檢索系統可能無法精準匹配新需求,因其檢索模式固化。大模型憑藉海量資料訓練出的泛化能力,能適應多樣表述。

知識更新和拓展方面

  • 知識更新困難:傳統知識工程方法構建的知識庫,如影視知識問答庫,靠人工錄入更新,新片上映、影視潮流變化後,知識更新滯後。而大模型可透過持續從網際網路抓取最新資訊,如新聞、影評等資料,自動學習新知識,依據新資訊即時最佳化回答,保持智慧電視知識服務前沿性。
  • 知識拓展能力有限:傳統 NLP 演算法訓練好的模型任務針對性強,如專用於電影推薦的協同過濾演算法模型,若拓展到跨領域影視知識科普,需重新設計訓練。大模型得益於海量資料學習的通用性,從影視娛樂知識可拓展到與之相關的文化歷史、科技特效等領域知識講解,滿足智慧電視使用者多元化需求。
因此在整個鏈路中,首先重點要解決的就是意圖識別問題,我們在意圖識別領域使用大模型對傳統NLP能力進行了全面升級,本文的重點也是介紹大模型意圖識別能力在智慧電視AI OS的核心鏈路中落地過程和思考。
意圖識別場景解析
意圖識別概念介紹
意圖識別(Intent Classification),是一種自然語言處理技術,用於分析使用者的輸入並將其對映到某個預定義的意圖類別。這種技術在問答機器人、智慧客服、虛擬助手等領域被廣泛使用。其目的是透過分析使用者的文字或語音輸入,識別使用者的詢問、請求或指示真正的目的,從而提供個性化、準確的服務。
例如,在智慧客服場景中,使用者輸入的語句可能比較模糊、複雜,包含著諮詢、抱怨、建議等多種潛在意圖,大模型透過意圖識別能力,剖析語句的語言模式、關鍵詞以及語義關聯等,準確判斷出使用者究竟是想要諮詢產品功能,還是對服務質量有所不滿,從而針對性地給出恰當回覆,有效提升客戶服務體驗。
在大模型的應用體系裡,意圖識別處於十分關鍵的位置,它就像是一座橋樑,連線著使用者模糊或明確的表達與大模型後續具體的任務執行,只有精準完成這一步驟,才能保證後續一系列動作的準確性和有效性,讓大模型真正成為幫助使用者解決問題、滿足需求的有力工具。
例如下面是一個企業內部對話機器人的例子:
在意圖層面有以下幾個概念:
意圖改寫:指在不改變使用者原始意圖的前提下,對使用者表達意圖的文字內容進行重新表述。例如,原始文字為 “明天的天氣”,改寫後的文字可以是 “幫我查一下明天的天氣狀況”。透過意圖改寫可以有效提高大模型輸出的準確率。
意圖分類:透過給不同的意圖分配特定標籤,便於大模型進行快速分類和處理。比如將意圖分為 “查詢類”“預訂類”“諮詢類” 等大的類別標籤,在 “查詢類” 下又可以細分出 “查詢天氣”“查詢航班” 等具體標籤。當用戶輸入內容後,大模型依據這些預設的標籤體系,能夠迅速判斷出所屬類別,從而採取相應的處理邏輯。
意圖槽位:意圖槽位在大模型意圖識別中起著關鍵作用,它就像是一個個精準捕捉使用者需求的 “小格子”。例如在使用者預訂機票的場景中,像出發地、目的地、出發時間、航班艙位等級等這些關鍵要素都可以看作是不同的意圖槽位。大模型透過分析使用者輸入的語句,嘗試將對應的資訊填充到相應的槽位裡,以此來更好地理解使用者究竟想要做什麼。
意圖置信度:是指模型在預測使用者意圖時的自信程度。通常用一個機率值來表示,機率越高,表示模型對預測的意圖越有信心。例如,模型預測使用者意圖是 “產品諮詢”,置信度為 0.9,這就表明模型比較確定使用者的意圖是產品諮詢;如果置信度為 0.4,說明模型對這個預測不是很有把握。
意圖識別在智慧電視中的落地挑戰
由於該場景處於電視C端業務的核心互動鏈路上,因此對意圖識別模組也提出了更高的要求。該場景的落地挑戰主要來自於以下幾個方面:
1.延遲要求:由於全鏈路較長,使用者對延遲容忍度低,因此對意圖識別模型的延遲要求也非常苛刻,通常需要在500ms-800ms左右必須返回全包,以供後續鏈路繼續處理業務。
2.準確性要求:C端使用者對整體體驗效果敏感,不準確的意圖會導致全鏈路功能失效,無法達到使用者預期。因此對意圖識別模型的準確性要求非常高,需要保證簡單指令100%準確率,複雜指令98%+準確率
3.即時資料處理能力:由於電視場景的特性,業務上需要涉及到最新的媒資資訊或網際網路上較新的梗,例如“老默吃魚”,單純靠基模能力無法有效理解。因此需要將一些較新的知識內容注入給模型
幾種落地方案選型
方案一:基模 + Prompt

方案特點:

開發成本低,適用於需要快速上線,對延時要求不高,分類相對簡單的場景。

模型選擇:

該方案主要靠基模的推理能力,需要根據分類難度和延時要求選擇不同模型。建議至少使用32b以上的模型,如qwen-plus、qwen-max。

方案說明:

Prompt的實現也有較多寫法,這裡是一些常用的實現技巧:

(1)CoT 思維鏈

CoT的核心在於引導模型逐步構建一個邏輯鏈,這個鏈由一系列相關的推理步驟組成,每個步驟都是基於前一步的結果。這種方法有助於模型更好地理解問題的上下文和複雜性,並且增強了模型輸出的解釋性和可信度。
# 思考步驟為了完成上述目標,請按照下面的過程,一步一步思考後完成: 1.首先需要先理解候選的意圖資訊共有如下{}個類別,每個意圖的含義或常見描述如下:{}

(2)Few-Shot 少樣本學習

大模型具備強大的少樣本學習能力,透過在prompt中引入few shot少樣本可有效提高大模型在意圖識別分類任務中的能力。例如:
2. 然後,觀察以下意圖識別分類案例,學習意圖識別分類任務的能力:{}

(3)特定準則重點說明

3. 意圖識別前,請重點學習並記住以下識別準則:{}
(4)輸出示例
4. 請以JSON格式進行輸出,輸出示例:{}

方案缺點:

  • 對垂類領域分類的識別有一定侷限性
  • 由於對模型推理能力有一定要求,選用大尺寸模型會帶來一定延遲開銷
基於以上原因,我們放棄了基模 + 提示詞的方案,該場景更適合業務相對簡單,延遲要求不敏感的業務場景。
方案二:基模 + Prompt + RAG

RAG介紹:

檢索增強生成(Retrieval-Augmented Generation,RAG)指的是在LLM回答問題之前從外部知識庫中檢索相關資訊,RAG有效地將LLM的引數化知識與非引數化的外部知識庫結合起來,使其成為實現大型語言模型的最重要方法之一
  • 早期的神經網路模型,在處理需要依賴外部知識或特定資訊的任務時遇到了瓶頸。
  • LLM的問題: 幻覺、依賴資訊過時、缺乏專業領域知識。
  • RAG的提出,是為了解決如何將廣泛的、分散式的外部資訊庫與生成模型相結合,從而提高模型在問答、摘要等任務中的效能和準確度。

方案特點:

鑑於方案一中垂類領域知識的問題,考慮加入RAG能力解決。透過在知識庫中上傳大量的意圖分類知識,使得該方案可以理解較為垂類或更個性化要求的分類判定邏輯。

模型選擇:

該方案引入了RAG能力,對模型推理要求不是很高,建議選用效能相對價效比較高的模型,如qwen-turbo、qwen-plus。

方案說明:

以下是一些建議的步驟:

(1)意圖語料結構設計

首先我們需要定義不同意圖的分類以及其槽位的設計,這些設計會和實際的業務場景以及後續承載具體實現的Agent密切相關,例如:
(2)資料生成
  • query語句生成:
這裡可以考慮給一些生產上使用者可能問的query示例,用LLM生成一批同義句,此處不再贅述
  • 意圖結果生成:
根據前面設計的意圖語料結構,使用大尺寸模型生成相關意圖分類和槽位,並可加入線上搜尋相關能力,程式碼示例和Prompt如下:
prompt = """# 角色你是一位意圖樣本生成專家,擅長根據給定的模板生成意圖及對應的槽位資訊。你能夠準確地解析使用者輸入,並將其轉化為結構化的意圖和槽位資料。## 技能### 技能1:解析使用者指令- **任務**:根據使用者提供的自然語言指令,識別出使用者的意圖。### 技能2:生成結構化意圖和槽位資訊- 意圖分類:video_search,music_search,information_search- 槽位分類:-- information_search: classification,video_category,video_name,video_season-- music_search: music_search,music_singer,music_tag,music_release_time-- video_search: video_actor,video_name,video_episode- **任務**:將解析出的使用者意圖轉換為結構化的JSON格式。  - 確保每個意圖都有相應的槽位資訊,不要自行編造槽位。  - 槽位資訊應包括所有必要的細節,如演員、劇名、集數、歌手、音樂標籤、釋出時間等。### 技能3:線上搜尋- 如果遇到關於電影情節的描述,可以調用搜索引擎獲取到電影名、演員等資訊稱補充到actor,name等槽位中### 輸出示例  - 以JSON格式輸出,例如:    -"這周杭州的天氣如何明天北京有雨嗎":{'infor_search':{'extra_info':['這周杭州的天氣如何明天北京有雨嗎']}} -"我一直在追趙麗穎的楚喬傳我看到第二十集了它已經更新了嗎我可以看下一集嗎":{'video_search':{'video_actor':['趙麗穎'],'video_name':['楚喬傳'],'video_episode':['第21集'],'extra_info':['我一直在追趙麗穎的楚喬傳我看到第二十集了它已經更新了嗎我可以看下一集嗎']}}## 限制- 只處理與意圖生成相關的任務。- 生成的意圖和槽位資訊必須準確且完整。- 在解析過程中,確保理解使用者的意圖並正確對映到相應的服務型別- 如果遇到未知的服務型別或槽位資訊,可以透過調用搜索工具進行補充和確認。- 直接輸出Json,不要輸出其他思考過程
生成後的用於知識庫的資料集格式如下:
[{"instruction":"播放一首七仔的歌曲我想聽他的經典老歌最好是70年代的音樂風格","output":"{'music_search':{'singer':['張學友'],'music_tag':['經典老歌'],'release_time':['70年代']}}"}]

(3)知識上傳和向量化

這裡有非常多成熟的方案可以選擇,可以考慮阿里雲百鍊平臺的RAG方案,此處不再贅述。

方案缺點:

  • 需要做資料預處理,有一定開發成本;
  • 知識庫內容較多或質量不佳時,可能引起模型幻覺和分類衝突;
  • 相比方案1,會增加向量召回部分的延遲,且模型要求依然在14b以上,有一定延遲問題;
因此,該方案也不太適用於電視C端互動鏈路上,但是方案二關於資料增強的思路還是值得借鑑的,基於這個思路,我們可以嘗試用小尺寸模型SFT的方案
方案三:使用小尺寸模型進行SFT

方案特點:

透過小尺寸模型解決延遲問題,透過微調解決資料增強問題

模型選擇:

一般而言,模型底座越大,下游任務效果越好,但是部署成本和推理代價相應增大。針對意圖識別的場景,建議從4B左右的大模型底座開始進行SFT和調參,當效果較大同時透過調參無法進一步提升時,建議換成7B的更大底座。超過10B的底座理論上能得到更好的結果,但是需要權衡實際的效果和成本問題,因此本場景使用7B的底座價效比較高。

微調方案:

選用LoRA方式進行微調
LoRA 原理(來源 LoRA 論文:LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS)
LoRa演算法在固定主預訓練引數的情況下,用支路去學習特定任務知識,來完成特定任務。它的假設為模型適應時的權重改變總是“低秩”的。訓練方法為在每層transfomer block旁邊引入一個並行低秩的支路,支路的輸入是transfomer block的輸入,然後將輸出和transfomer block的輸出相加。訓練完後將原始權重加上LoRA訓練的權重(

),最終使得模型結構不變。

方案說明:

SFT的大致流程如下:

(1)意圖語料結構設計

參考方案二中的意圖預料設計,此處不再贅述

(2)樣本生成

樣本生成有很多方式,比如前面提到的LLM生成或是引入一些資料預處理工具。筆者這裡使用的是PAI-iTag工具。首先,將用於iTag標註的資料註冊到PAI資料集,該資料集為manifest格式檔案,內容示例如下:
{"data":{"instruction": "我想聽音樂"}}{"data":{"instruction": "太吵了,把聲音開小一點"}}{"data":{"instruction": "我不想聽了,把歌關了吧"}}{"data":{"instruction": "我想去杭州玩,幫我查下天氣預報"}}
標註完成後可以將標註結果匯出至OSS,在本示例中,輸出檔案內容如下:
{"data":{"instruction":"我想聽音樂","_itag_index":""},"label-1787402095227383808":{"results":[{"questionId":"2","data":"play_music()","markTitle":"output","type":"survey/value"}]},"abandonFlag":0,"abandonRemark":null}{"data":{"instruction":"太吵了,把聲音開小一點","_itag_index":""},"label-1787402095227383808":{"results":[{"questionId":"2","data":"volume_down()","markTitle":"output","type":"survey/value"}]},"abandonFlag":0,"abandonRemark":null}{"data":{"instruction":"我不想聽了,把歌關了吧","_itag_index":""},"label-1787402095227383808":{"results":[{"questionId":"2","data":"music_exit()","markTitle":"output","type":"survey/value"}]},"abandonFlag":0,"abandonRemark":null}{"data":{"instruction":"我想去杭州玩,幫我查下天氣預報","_itag_index":""},"label-1787402095227383808":{"results":[{"questionId":"2","data":"weather_search(杭州)","markTitle":"output","type":"survey/value"}]},"abandonFlag":0,"abandonRemark":null}
標註完成的資料格式說明參考標註資料格式概述。為了在PAI-ModelGallery
種使用標註資料進行模型訓練,需要將上述檔案轉化為PAI-ModelGallery
接受的訓練資料格式,可以參考如下Python指令碼:
# 輸入檔案路徑和輸出檔案路徑input_file_path = 'test_json.manifest'output_file_path = 'train.json'converted_data = []withopen(input_file_path, 'r', encoding='utf-8') asfile:for line infile:data = json.loads(line) instruction = data['data']['instruction']forkeyin data.keys():if key.startswith('label-'):output = data[key]['results'][0]['data'] converted_data.append({'instruction': instruction, 'output': output}) breakwithopen(output_file_path, 'w', encoding='utf-8') asoutfile: json.dump(converted_data, outfile, ensure_ascii=False, indent=4)

(3)模型訓練引數設定

  • 全引數微調 OR 輕量化微調(LoRA和QLoRA)
全引數微調消耗計算資源最多,而且容易使大模型產生災難性遺忘,LoRA和QLoRA有效地避免了這個問題。另一方面,QLoRA由於引數精度低,容易對下游任務的效果產生不利影響。綜合考慮,使用LoRA演算法進行微調。
  • 全域性批次大小
全域性批次大小=卡數*per_device_train_batch_size*gradient_accumulation_steps
這裡在GPU視訊記憶體允許的情況下儘可能調大batch size,可以使得模型更快收斂到最優解,同時具有較高的泛化能力。
  • 序列長度
序列長度對視訊記憶體消耗和訓練效果有較大的影響,過小的序列長度雖然節省了視訊記憶體,但是導致某些比較長的訓練資料集被切斷,造成不利影響;過大的序列長度又會造成視訊記憶體的浪費。從意圖識別的場景來看,根據實際資料的長度,選擇64/128/256的長度比較合適。
  • 學習率
如果訓練資料質量比較差,訓練效果一般會受影響,所以在資料標註的時候需要進行充分的質量校驗。同時,由於LoRA訓練一般引數調整空間不大,學習率預設可以進行偏大設定,例如1e-4左右,當訓練loss下降過慢或者不收斂時,建議適當調大學習率,例如3e-4或者5e-4不建議使用1e-3這個量級的學習率,容易得不到最佳化的結果。
  • 模型選擇
一般而言,模型底座越大,下游任務效果越好,但是部署成本和推理代價相應增大。針對意圖識別的場景,建議從4B左右的大模型底座開始進行SFT和調參,當效果較大同時透過調參無法進一步提升時,建議換成7B的更大底座。超過10B的底座理論上能得到更好的結果,但是需要權衡實際的效果和成本問題,因此,因此本場景使用7B的底座價效比較高。
(4)啟動訓練任務
值得注意的是,如果需要在訓練過程中改變預設的system_prompt,讓大模型扮演某種特定的角色,可以在Qwen1.5系列模型的訓練中配置自定義的
system_prompt,例如“你是一個意圖識別專家,可以根據使用者的問題識別出意圖,並返回對應的意圖和引數”。在這種情況下,給定一個訓練樣本:
[ {"instruction":"我想聽音樂","output":"play_music()" }]
實際用於訓練的資料格式如下:
<|im_start|>system\n你是一個意圖識別專家,可以根據使用者的問題識別出意圖,並返回對應的意圖和引數<|im_end|>\n<|im_start|>user\n我想聽音樂<|im_end|>\n<|im_start|>assistant\nplay_music()<|im_end|>\n
當設定apply_chat_template為true並且新增system_prompt,演算法會自行對訓練資料進行擴充套件,無需關注執行細節。

(5)模型離線評測

當模型訓練結束後,可以使用如下Python指令碼進行模型效果的評測。假設評測資料如下:
[ {"instruction":"想知道的十年是誰唱的?","output":"music_query_player(十年)" }, {"instruction":"今天北京的天氣怎麼樣?","output":"weather_search(杭州)" }]
評測指令碼如下所示:
#encoding=utf-8from transformers import AutoModelForCausalLM, AutoTokenizerimport jsonfrom tqdm import tqdmdevice = "cuda" # the device to load the model onto# 修改模型路徑model_name = '/mnt/workspace/model/qwen14b-lora-3e4-256-train/'print(model_name)model = AutoModelForCausalLM.from_pretrained(    model_name,    torch_dtype="auto",    device_map="auto")tokenizer = AutoTokenizer.from_pretrained(model_name)count = 0ecount = 0# 修改訓練資料路徑test_data = json.load(open('/mnt/workspace/data/testdata.json'))system_prompt = '你是一個意圖識別專家,可以根據使用者的問題識別出意圖,並返回對應的函式呼叫和引數。'for i in tqdm(test_data[:]):    prompt = '<|im_start|>system\n' + system_prompt + '<|im_end|>\n<|im_start|>user\n' + i['instruction'] + '<|im_end|>\n<|im_start|>assistant\n'    gold = i['output']    gold = gold.split(';')[0] if';' in gold else gold    model_inputs = tokenizer([prompt], return_tensors="pt").to(device)    generated_ids = model.generate(        model_inputs.input_ids,        max_new_tokens=64,        pad_token_id=tokenizer.eos_token_id,        eos_token_id=tokenizer.eos_token_id,        do_sample=False    )    generated_ids = [        output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)    ]    pred = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]if gold.split('(')[0] == pred.split('(')[0]:        count += 1        gold_list = set(gold.strip()[:-1].split('(')[1].split(','))        pred_list = set(pred.strip()[:-1].split('(')[1].split(','))if gold_list == pred_list:            ecount += 1else:        passprint("意圖識別準確率:", count/len(test_data))print("引數識別準確率:", ecount/len(test_data))

(6)模型部署

部署的推理服務支援使用ChatLLM WebUI進行即時互動,也可以使用API進行模型推理,具體使用方法參考5分鐘使用EAS一鍵部署LLM大語言模型應用:
https://help.aliyun.com/zh/pai/use-cases/deploy-llm-in-eas
以下給出一個示例request客戶端呼叫:
import argparseimport jsonfrom typing import Iterable, Listimport requestsdef post_http_request(prompt: str,                      system_prompt: str,                      history: list,                      host: str,                      authorization: str,                      max_new_tokens: int = 2048,                      temperature: float = 0.95,                      top_k: int = 1,                      top_p: float = 0.8,                      langchain: bool = False,                      use_stream_chat: bool = False) -> requests.Response:    headers = {"User-Agent": "Test Client","Authorization": f"{authorization}"    }    pload = {"prompt": prompt,"system_prompt": system_prompt,"top_k": top_k,"top_p": top_p,"temperature": temperature,"max_new_tokens": max_new_tokens,"use_stream_chat": use_stream_chat,"history": history    }    response = requests.post(host, headers=headers,                             json=pload, stream=use_stream_chat)return responsedef get_response(response: requests.Response) -> List[str]:    data = json.loads(response.content)    output = data["response"]    history = data["history"]return output, historyif __name__ == "__main__":    parser = argparse.ArgumentParser()    parser.add_argument("--top-k", type=int, default=4)    parser.add_argument("--top-p", type=float, default=0.8)    parser.add_argument("--max-new-tokens", type=int, default=2048)    parser.add_argument("--temperature", type=float, default=0.95)    parser.add_argument("--prompt", type=str, default="How can I get there?")    parser.add_argument("--langchain", action="store_true")    args = parser.parse_args()    prompt = args.prompt    top_k = args.top_k    top_p = args.top_p    use_stream_chat = False    temperature = args.temperature    langchain = args.langchain    max_new_tokens = args.max_new_tokens    host = "EAS服務公網地址"    authorization = "EAS服務公網Token"    print(f"Prompt: {prompt!r}\n", flush=True)    # 在客戶端請求中可設定語言模型的system prompt。    system_prompt = "你是一個意圖識別專家,可以根據使用者的問題識別出意圖,並返回對應的意圖和引數"    # 客戶端請求中可設定對話的歷史資訊,客戶端維護當前使用者的對話記錄,用於實現多輪對話。通常情況下可以使用上一輪對話返回的histroy資訊,history格式為List[Tuple(str, str)]。    history = []    response = post_http_request(        prompt, system_prompt, history,        host, authorization,        max_new_tokens, temperature, top_k, top_p,        langchain=langchain, use_stream_chat=use_stream_chat)    output, history = get_response(response)    print(f" --- output: {output} \n --- history: {history}", flush=True)# 服務端返回JSON格式的響應結果,包含推理結果與對話歷史。def get_response(response: requests.Response) -> List[str]:    data = json.loads(response.content)    output = data["response"]    history = data["history"]return output, history
在智慧電視意圖識別場景中,為了保證使用者的互動體驗,通常要求更高的延時,因此建議使用PAI提供的BladeLLM推理引擎進行LLM服務的部署。

(7)Prompt

因為主要靠微調提升效果,Promp的寫法相對簡單,不再預置業務規則和思維鏈:
{"role": "system", "content": "你是個意圖識別專家,你要透過使用者的輸入,識別使用者的意圖以及槽位資訊,注意:不要新增沒有的意圖和槽位。"}
幾種方案的對比:
新的問題:準確率、時效性、成本
在實際的生成鏈路上,我們發現要保證準確率、時效性、以及成本之間,還有一些工作要做,主要包含以下幾個靈魂拷問:
1.如何保證生產準確率持續符合要求?
網際網路上的資訊更新迭代很快,尤其是在娛樂性質較重的媒資類產品上,幾乎每天都會產生新的電視/電影/音樂等資訊;一些網際網路上的梗也持續出現,比如“老默吃魚”,“蔣欣在這裡”等等,使用者個性化的問法也是層出不窮,如何能持續保證生產的準確率符合98%以上的預期是一個難題。
2.如何在生產環境上對結果糾錯?
電視場景的互動是以語音為主,不太涉及觸屏等精細化互動操作。如果客戶對某個答案不滿意,並不會像PC或手機上的智慧機器人那樣有一個“點踩”的反饋渠道。出現大量事實性錯誤時,只能透過使用者投訴得到反饋,這會極大有損使用者體驗。所以如何拿到生產的意圖結論對錯成為一個待解決的問題。
3.海量C端使用者的指令無法窮舉,大量的訓練集如何產生?
我們透過微調解決垂直業務資料問題,前期我們準備的訓練資料只能解決一小部分問題,實際生產上微調模型是需要不停的迭代的,那麼微調的資料要從要哪裡來也是一個很重要的問題。
4.訓練集不停變大,反覆SFT耗時耗力,有沒有自動化的方案?
當我們拿到了訓練集後,需要人工在平臺上進行模型訓練和部署,如果這個操作頻率精細化到每天都要處理,那麼無疑對人力成本的消耗是巨大的。所以有沒有一個全自動化的方案能幫我們解決這些問題?
進階方案:自動質檢和自動微調工程鏈路
透過設計完整的離線質檢工程鏈路,持續自動訓練和部署最新模型,解決生產準確率、訓練集和微調模型成本的問題。
該方案透過多步驟處理流程,實現了自動對線上意圖質檢及自動重新訓練的流程。總體上分為線上流程和離線流程兩部分,以下是詳細的流程描述:
線上流程:
1.使用者的query先經過一道意圖快取庫,該庫直接以query為key,將曾經正確返回的意圖結果儲存在es中。當快取被命中時直接將結果返回,不再走後續鏈路,以此提高響應速度和保證準確性。該快取庫主要是為一些簡單意圖如系統指令、媒資名搜尋做快速結果返回
2.如果未命中快取,則走到後續的模型推理鏈路。當前使用的是微調後的qwen-7b模型
離線流程:
1.當大模型輸出意圖推理結果後,會非同步將query+reponse傳入給一個意圖最佳化應用,作為整體質檢的入口
2.呼叫一個大尺寸模型,例如qwen-max對結果進行質檢。質檢規則是輸出response相對於result的得分情況,滿分為1分,只有0.9分以上的答案才認為是正確的
3.如果意圖準確,則重新將此次的意圖結果寫進快取中,方便下次呼叫讀取
4.如果意圖得分低於0.9,認為該意圖生成質量不佳,此時會嘗試使用大尺寸模型如qwen-max進行意圖的重新生成。需要注意的是,此質檢agent會引入LLM即時搜尋能力,保證對一些較新的query資訊做好理解
5.當意圖生成agent的答案重新透過質檢後,會更新到訓練集中,以供下一次SFT使用
落地效果
在某國產頭部電視廠家落地過程中,最終經過多輪技術選型,我們決策使用PAI平臺進行qwen-7b模型的訓練和推理部署,該方案准確率和延遲上都有較大優勢,平均延遲500ms,生產即時準確率達到98%+。
結尾
隨著電視技術的迅猛發展和使用者互動模式的日益多樣化,意圖識別技術在增強使用者體驗中發揮著不可或缺的作用。本文聚焦於電視環境中大模型意圖識別的核心技術、所面臨的挑戰以及當前的解決方案。
AI大模型技術還在不斷高速迭代更新,作為阿里雲大模型技術服務團隊將陪伴客戶共同成長,一起見證更加智慧且人性化的電視互動體驗的誕生。透過持續最佳化和升級現有的大模型結構,並融入多維度的資料來源——例如語音情感分析與視覺內容感知等先進技術,未來的電視裝置將不僅能夠準確理解使用者的指令,還能夠預判其需求,提供超越預期的個性化服務。
這種進步將重新定義觀眾與電視之間的互動方式,開啟智慧家居娛樂的新紀元。
AI編碼,十倍提速,通義靈碼引領研發新正規化
本方案提出以通義靈碼為核心的智慧開發流程。通義靈碼在程式碼生成、註釋新增及單元測試方面實現快速生成,雲效則作為程式碼管理和持續整合平臺,最終將應用程式部署到函式計算 FC 平臺。   
點選閱讀原文檢視詳情。

相關文章