---
# System prepended metadata

title: 用LangChain連結TAIDE與GPT3.5-turbo
tags: [Templates, Documentation]

---

---
title: 'Project documentation template'
disqus: hackmd
---

第二部分：以LangChain連接TAIDE與GPT模型
===
* LangChain官網 ： https://www.langchain.com/
* RAG論文：https://arxiv.org/abs/2005.11401

## RAG概念圖
![螢幕擷取畫面 2024-06-03 233502](https://hackmd.io/_uploads/rkQaMvi4A.png)





先載入TAIDE 模型
---
考慮到硬體設備的問題，這裡使用TAIDE-LX-7B-Chat。

```gherkin=
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline, BitsAndBytesConfig
from torch import bfloat16

my_token ='輸入你的Huggingface token'
```
## 注意！！！請確認python、CUDA以及Pytorch的版本符合要求

此使用版本：
python : 3.11.7
CUDA : 11.8
Pytorch : 2.1
```gherkin=
model_name = "taide/TAIDE-LX-7B-Chat"
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=False, token=my_token)
model = AutoModelForCausalLM.from_pretrained(model_name, load_in_4bit=True, device_map='auto', token=my_token)
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)

sys = '你是一個來自台灣的AI助理，你的名字是 TAIDE，樂於以台灣人的立場幫助使用者，會用繁體中文回答問題。'
question1 = '請給我一篇冒險故事'
chat = [
    {"role": "system", "content": f"{sys}"},
    {"role": "user", "content": f"{question1}"},
]
prompt = tokenizer.apply_chat_template(chat, tokenize=False)
x = pipe(chat, max_new_tokens=1024)
print(f"TAIDE: {x}")
```
> 來源為TAIDE官網：https://taide.tw/index

TAIDE輸出
```gherkin=
TAIDE: [{'generated_text': [{'role': 'system', 'content': '你是一個來自台灣的AI助理，你的名字是 TAIDE，樂於以台灣人的立場幫助使用者，會用繁體中文回答問題。'}, {'role': 'user', 'content': '請給我一篇冒險故事'}, {'role': 'assistant', 'content': ' 在遙遠的福爾摩沙島上，住著一位名叫小明的青年。小明一直嚮往著冒險的生活，他夢想著有一天能踏上未知的土地，探索世界之大。終於，一天，他收到了一封神秘的信件，信上寫著一個古老的傳說，關於一座隱藏在山雲間的神祕寶藏。這讓小明心潮澎湃，決定踏上旅程，尋找那座傳說中的寶藏。\n\n小明在村裡召集了幾位志同道合的朋友，他們各有所長，有擅長狩獵的阿力，有精通航海的阿文，還有能說多國語言的阿傑。大家各司其職，準備出發尋找傳說中的寶藏。\n\n在旅程中，他們經歷了種種考驗。在穿越茂密的森林時，他們遇上了兇猛的野獸，幸虧阿力及時出現，用他的狩獵技巧將野獸擊退。在渡過湍急的河流時，阿文發揮了他在航海方面的專長，帶領大家安全抵達對岸。而在攀登高山時，眾人因缺乏經驗，一度面臨了失溫的危險，幸好阿傑的語言天賦幫大家化解了危機，他們遇到了一位當地原住民，從他那兒學到了如何在惡劣環境下生存。\n\n經過重重困難，小明和夥伴們終於抵達了傳說中的寶藏之地。他們發現那座寶藏的所在地竟是一座被遺忘的古城，古城中充斥著古老的氣息和神秘的氣息。在探索古城的過程中，他們還發現了許多珍貴的文物和歷史遺跡，這些寶藏比他們想像的還要豐富。\n\n在完成尋找寶藏的任務後，小明和夥伴們不捨地告別了這座古城，帶著滿滿的回憶和收穫回到了家鄉。這次冒險之旅讓小明和夥伴們見識到了世界的廣闊和歷史的深度，也讓他們明白了團隊合作和互相扶持的重要性。從此，他們將帶著這些寶貴的經驗，繼續在世界的舞臺上寫下屬於自己的傳奇。 '}]}]

在遙遠的福爾摩沙島上，住著一位名叫小明的青年。小明一直嚮往著冒險的生活，他夢想著有一天能踏上未知的土地，探索世界之大。
終於，一天，他收到了一封神秘的信件，信上寫著一個古老的傳說，關於一座隱藏在山雲間的神祕寶藏。這讓小明心潮澎湃，決定踏上旅程，尋找那座傳說中的寶藏。
小明在村裡召集了幾位志同道合的朋友，他們各有所長，有擅長狩獵的阿力，有精通航海的阿文，還有能說多國語言的阿傑。大家各司其職，準備出發尋找傳說中的寶藏。在旅程中，他們經歷了種種考驗。
在穿越茂密的森林時，他們遇上了兇猛的野獸，幸虧阿力及時出現，用他的狩獵技巧將野獸擊退。在渡過湍急的河流時，阿文發揮了他在航海方面的專長，帶領大家安全抵達對岸。而在攀登高山時，眾人因缺乏經驗，一度面臨了失溫的危險，幸好阿傑的語言天賦幫大家化解了危機，他們遇到了一位當地原住民，從他那兒學到了如何在惡劣環境下生存。
經過重重困難，小明和夥伴們終於抵達了傳說中的寶藏之地。
他們發現那座寶藏的所在地竟是一座被遺忘的古城，古城中充斥著古老的氣息和神秘的氣息。
在探索古城的過程中，他們還發現了許多珍貴的文物和歷史遺跡，這些寶藏比他們想像的還要豐富。
在完成尋找寶藏的任務後，小明和夥伴們不捨地告別了這座古城，帶著滿滿的回憶和收穫回到了家鄉。
這次冒險之旅讓小明和夥伴們見識到了世界的廣闊和歷史的深度，也讓他們明白了團隊合作和互相扶持的重要性。從此，他們將帶著這些寶貴的經驗，繼續在世界的舞臺上寫下屬於自己的傳奇。
```
使用LangChain載入GPT3.5-turbo
---
LangChain是一個方便的框架，整合並簡化了許多大型語言模型
```gherkin=
import openai
from langchain.chains import LLMChain, SequentialChain
from langchain.prompts import PromptTemplate
from langchain.chat_models import ChatOpenAI

import os

os.environ["OPENAI_API_KEY"] = '輸入你的OpenAI API'
gpt_llm = ChatOpenAI(model="gpt-3.5-turbo",openai_api_key=os.getenv("OPENAI_API_KEY"))

```
## 先幫TAIDE模型定義一些函數並整理一下
由於TAIDE是llama系列的語言模型，不像openai有generate這個方便的指令可以使用，因此我們需要先定義一個class來達成類似效果。
```gherkin=
class TAIDE:
    def __init__(self, pipe):
        self.pipeline = pipe
        
###使用pipeline來根據我們所指定的prompt生成回覆
    def generate(self, prompt):
        result = self.pipeline(prompt, max_length=1024, num_return_sequences=1)
        return result[0]['generated_text']

taide_llm = TAIDE(pipe)
```

使用LangChain連接兩個語言模型
---
所輸入的prompt會藉由PromptTemplate獲得完整的任務提示，並一同輸入語言模型中，最後生成完整的回覆。

這裡第一層的語言模型為gpt3.5-turbo，我們將它的輸出做為第二層TAIDE的prompt，使TAIDE獲得更好的輸出。
```gherkin=
prompt_template1 = PromptTemplate(input_variables=["topic"], template="生成並介紹故事關於{topic}.")
prompt_template2 = PromptTemplate(input_variables=["story"], template="改進接下來的故事: {story}")
chain1 = LLMChain(prompt=prompt_template1, llm=gpt_llm)

class ImprovementChain:
    def __init__(self, initial_chain, improver_llm, prompt_template):
        self.initial_chain = initial_chain
        self.improver_llm = improver_llm
        self.prompt_template = prompt_template

    def run(self, inputs):
        initial_output = self.initial_chain.run(inputs)
        improved_prompt = self.prompt_template.format(story=initial_output)
        improved_output = self.improver_llm.generate(improved_prompt)
        return improved_output
```
感謝GPT與網路上的陌生人的協助，沒有你們，我根本弄不出這些：）


## 輸出

```gherkin=
improvement_chain = ImprovementChain(initial_chain=chain1, improver_llm=taide_llm, prompt_template=prompt_template2)

topic = "以繁體中文生成一個冒險故事"
inputs = {"topic": topic}

improved_story = improvement_chain.run(inputs)
print(improved_story)
```
```gherkin=

改進接下來的故事: 在一個遙遠的地方，有一座神秘的森林，被稱為「幽靈森林」。傳說中，只有勇敢的冒險者才能進入這片森林，而且沒有人能確切地描述這裡的奧秘。

有一天，一名名叫小明的年輕勇士決定踏入幽靈森林，探索其中的秘密。他穿過樹林，穿越沼澤，最終來到一座古老的城堡。城堡的大門敞開著，小明毫不猶豫地走了進去。

城堡內部充滿了古老的符文和寶藏，但也充滿了危險。小明面臨著許多考驗和障礙，但他毫不畏懼，堅定地前行。最終，他找到了一個魔法寶盒，裡面藏著一個神秘的寶石。

當小明拿起寶石的一瞬間，整個城堡開始震動，一個邪惡的巨龍出現在他面前。小明知道這是最後的考驗，他毅然決定與巨龍展開一場生死搏鬥。

經過激烈的戰鬥，小明終於戰勝了巨龍，取得了寶石。他離開城堡，回到了外面的森林，面對著陽光和自由。他成功完成了冒險，並獲得了無上的榮耀和寶藏。

從此以後，小明成為了傳說中的英雄，他的勇氣和智慧被人們傳頌，幽靈森林也因他的冒險而變得更加神秘和美麗。而那顆神秘的寶石，也被稱為「勇氣之心」，成為人們嚮往的寶物。

故事結束。 
```
