【基礎島·第5關】XTuner 微調個人小助手認知

陈佳佳|Tech發表於2024-09-28

目錄
  • 1. 基本概念
  • 2. 準備工作
    • 2.1 建立cuda12.2-conda的開發機
    • 2.2 環境準備
    • 2.3 安裝xtuner
    • 2.4 模型準備
  • 3. 快速開始
    • 3.1 微調前
    • 3.2 指令跟隨微調
    • 3.3 微調後
  • 1. 前置知識
  • 2. 環境、模型準備
    • 2.1 配置開發機環境
    • 2.2 安裝 Llamaindex
    • 2.3 下載 Sentence Transformer 模型
    • 2.4 下載 NLTK 相關資源
  • 3. LlamaIndex HuggingFaceLLM
  • 4. LlamaIndex RAG
  • 5. LlamaIndex web 圖形化介面

1. 基本概念

//todo

2. 準備工作

2.1 建立cuda12.2-conda的開發機

2.2 環境準備

# 建立虛擬環境
conda create -n xtuner0121 python=3.10 -y

# 啟用虛擬環境(注意:後續的所有操作都需要在這個虛擬環境中進行)
conda activate xtuner0121

# 安裝一些必要的庫
conda install pytorch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 pytorch-cuda=12.1 -c pytorch -c nvidia -y
# 安裝其他依賴
pip install transformers==4.39.3
pip install streamlit==1.36.0

2.3 安裝xtuner

# 建立一個目錄,用來存放原始碼
mkdir -p /root/InternLM/code

cd /root/InternLM/code

git clone -b v0.1.21  https://github.com/InternLM/XTuner /root/InternLM/code/XTuner

# 進入到原始碼目錄
cd /root/InternLM/code/XTuner
conda activate xtuner0121

# 執行安裝
pip install -e '.[deepspeed]'

驗證結果

xtuner version

2.4 模型準備

開發機中已經提供了模型本地檔案,不需要再下載。透過以下程式碼一鍵透過符號連結的方式連結到模型檔案,這樣既節省了空間,也便於管理。

# 建立一個目錄,用來存放微調的所有資料,後續的所有操作都在該路徑中進行
mkdir -p /root/InternLM/XTuner

cd /root/InternLM/XTuner

mkdir -p Shanghai_AI_Laboratory

ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b Shanghai_AI_Laboratory/internlm2-chat-1_8b

安裝tree命令來慣常目錄結構

apt-get install -y tree

tree -l

3. 快速開始

3.1 微調前

準備一個Streamlit程式的指令碼

import copy
import warnings
from dataclasses import asdict, dataclass
from typing import Callable, List, Optional

import streamlit as st
import torch
from torch import nn
from transformers.generation.utils import (LogitsProcessorList,
                                           StoppingCriteriaList)
from transformers.utils import logging

from transformers import AutoTokenizer, AutoModelForCausalLM  # isort: skip

logger = logging.get_logger(__name__)


model_name_or_path = "/root/InternLM/XTuner/Shanghai_AI_Laboratory/internlm2-chat-1_8b"

@dataclass
class GenerationConfig:
    # this config is used for chat to provide more diversity
    max_length: int = 2048
    top_p: float = 0.75
    temperature: float = 0.1
    do_sample: bool = True
    repetition_penalty: float = 1.000


@torch.inference_mode()
def generate_interactive(
    model,
    tokenizer,
    prompt,
    generation_config: Optional[GenerationConfig] = None,
    logits_processor: Optional[LogitsProcessorList] = None,
    stopping_criteria: Optional[StoppingCriteriaList] = None,
    prefix_allowed_tokens_fn: Optional[Callable[[int, torch.Tensor],
                                                List[int]]] = None,
    additional_eos_token_id: Optional[int] = None,
    **kwargs,
):
    inputs = tokenizer([prompt], padding=True, return_tensors='pt')
    input_length = len(inputs['input_ids'][0])
    for k, v in inputs.items():
        inputs[k] = v.cuda()
    input_ids = inputs['input_ids']
    _, input_ids_seq_length = input_ids.shape[0], input_ids.shape[-1]
    if generation_config is None:
        generation_config = model.generation_config
    generation_config = copy.deepcopy(generation_config)
    model_kwargs = generation_config.update(**kwargs)
    bos_token_id, eos_token_id = (  # noqa: F841  # pylint: disable=W0612
        generation_config.bos_token_id,
        generation_config.eos_token_id,
    )
    if isinstance(eos_token_id, int):
        eos_token_id = [eos_token_id]
    if additional_eos_token_id is not None:
        eos_token_id.append(additional_eos_token_id)
    has_default_max_length = kwargs.get(
        'max_length') is None and generation_config.max_length is not None
    if has_default_max_length and generation_config.max_new_tokens is None:
        warnings.warn(
            f"Using 'max_length''s default ({repr(generation_config.max_length)}) \
                to control the generation length. "
            'This behaviour is deprecated and will be removed from the \
                config in v5 of Transformers -- we'
            ' recommend using `max_new_tokens` to control the maximum \
                length of the generation.',
            UserWarning,
        )
    elif generation_config.max_new_tokens is not None:
        generation_config.max_length = generation_config.max_new_tokens + \
            input_ids_seq_length
        if not has_default_max_length:
            logger.warn(  # pylint: disable=W4902
                f"Both 'max_new_tokens' (={generation_config.max_new_tokens}) "
                f"and 'max_length'(={generation_config.max_length}) seem to "
                "have been set. 'max_new_tokens' will take precedence. "
                'Please refer to the documentation for more information. '
                '(https://huggingface.co/docs/transformers/main/'
                'en/main_classes/text_generation)',
                UserWarning,
            )

    if input_ids_seq_length >= generation_config.max_length:
        input_ids_string = 'input_ids'
        logger.warning(
            f"Input length of {input_ids_string} is {input_ids_seq_length}, "
            f"but 'max_length' is set to {generation_config.max_length}. "
            'This can lead to unexpected behavior. You should consider'
            " increasing 'max_new_tokens'.")

    # 2. Set generation parameters if not already defined
    logits_processor = logits_processor if logits_processor is not None \
        else LogitsProcessorList()
    stopping_criteria = stopping_criteria if stopping_criteria is not None \
        else StoppingCriteriaList()

    logits_processor = model._get_logits_processor(
        generation_config=generation_config,
        input_ids_seq_length=input_ids_seq_length,
        encoder_input_ids=input_ids,
        prefix_allowed_tokens_fn=prefix_allowed_tokens_fn,
        logits_processor=logits_processor,
    )

    stopping_criteria = model._get_stopping_criteria(
        generation_config=generation_config,
        stopping_criteria=stopping_criteria)
    logits_warper = model._get_logits_warper(generation_config)

    unfinished_sequences = input_ids.new(input_ids.shape[0]).fill_(1)
    scores = None
    while True:
        model_inputs = model.prepare_inputs_for_generation(
            input_ids, **model_kwargs)
        # forward pass to get next token
        outputs = model(
            **model_inputs,
            return_dict=True,
            output_attentions=False,
            output_hidden_states=False,
        )

        next_token_logits = outputs.logits[:, -1, :]

        # pre-process distribution
        next_token_scores = logits_processor(input_ids, next_token_logits)
        next_token_scores = logits_warper(input_ids, next_token_scores)

        # sample
        probs = nn.functional.softmax(next_token_scores, dim=-1)
        if generation_config.do_sample:
            next_tokens = torch.multinomial(probs, num_samples=1).squeeze(1)
        else:
            next_tokens = torch.argmax(probs, dim=-1)

        # update generated ids, model inputs, and length for next step
        input_ids = torch.cat([input_ids, next_tokens[:, None]], dim=-1)
        model_kwargs = model._update_model_kwargs_for_generation(
            outputs, model_kwargs, is_encoder_decoder=False)
        unfinished_sequences = unfinished_sequences.mul(
            (min(next_tokens != i for i in eos_token_id)).long())

        output_token_ids = input_ids[0].cpu().tolist()
        output_token_ids = output_token_ids[input_length:]
        for each_eos_token_id in eos_token_id:
            if output_token_ids[-1] == each_eos_token_id:
                output_token_ids = output_token_ids[:-1]
        response = tokenizer.decode(output_token_ids)

        yield response
        # stop when each sentence is finished
        # or if we exceed the maximum length
        if unfinished_sequences.max() == 0 or stopping_criteria(
                input_ids, scores):
            break


def on_btn_click():
    del st.session_state.messages


@st.cache_resource
def load_model():
    model = (AutoModelForCausalLM.from_pretrained(model_name_or_path,
                                                  trust_remote_code=True).to(
                                                      torch.bfloat16).cuda())
    tokenizer = AutoTokenizer.from_pretrained(model_name_or_path,
                                              trust_remote_code=True)
    return model, tokenizer


def prepare_generation_config():
    with st.sidebar:
        max_length = st.slider('Max Length',
                               min_value=8,
                               max_value=32768,
                               value=2048)
        top_p = st.slider('Top P', 0.0, 1.0, 0.75, step=0.01)
        temperature = st.slider('Temperature', 0.0, 1.0, 0.1, step=0.01)
        st.button('Clear Chat History', on_click=on_btn_click)

    generation_config = GenerationConfig(max_length=max_length,
                                         top_p=top_p,
                                         temperature=temperature)

    return generation_config


user_prompt = '<|im_start|>user\n{user}<|im_end|>\n'
robot_prompt = '<|im_start|>assistant\n{robot}<|im_end|>\n'
cur_query_prompt = '<|im_start|>user\n{user}<|im_end|>\n\
    <|im_start|>assistant\n'


def combine_history(prompt):
    messages = st.session_state.messages
    meta_instruction = ('')
    total_prompt = f"<s><|im_start|>system\n{meta_instruction}<|im_end|>\n"
    for message in messages:
        cur_content = message['content']
        if message['role'] == 'user':
            cur_prompt = user_prompt.format(user=cur_content)
        elif message['role'] == 'robot':
            cur_prompt = robot_prompt.format(robot=cur_content)
        else:
            raise RuntimeError
        total_prompt += cur_prompt
    total_prompt = total_prompt + cur_query_prompt.format(user=prompt)
    return total_prompt


def main():
    # torch.cuda.empty_cache()
    print('load model begin.')
    model, tokenizer = load_model()
    print('load model end.')


    st.title('InternLM2-Chat-1.8B')

    generation_config = prepare_generation_config()

    # Initialize chat history
    if 'messages' not in st.session_state:
        st.session_state.messages = []

    # Display chat messages from history on app rerun
    for message in st.session_state.messages:
        with st.chat_message(message['role'], avatar=message.get('avatar')):
            st.markdown(message['content'])

    # Accept user input
    if prompt := st.chat_input('What is up?'):
        # Display user message in chat message container
        with st.chat_message('user'):
            st.markdown(prompt)
        real_prompt = combine_history(prompt)
        # Add user message to chat history
        st.session_state.messages.append({
            'role': 'user',
            'content': prompt,
        })

        with st.chat_message('robot'):
            message_placeholder = st.empty()
            for cur_response in generate_interactive(
                    model=model,
                    tokenizer=tokenizer,
                    prompt=real_prompt,
                    additional_eos_token_id=92542,
                    **asdict(generation_config),
            ):
                # Display robot response in chat message container
                message_placeholder.markdown(cur_response + '▌')
            message_placeholder.markdown(cur_response)
        # Add robot response to chat history
        st.session_state.messages.append({
            'role': 'robot',
            'content': cur_response,  # pylint: disable=undefined-loop-variable
        })
        torch.cuda.empty_cache()


if __name__ == '__main__':
    main()

執行:

conda activate xtuner0121

streamlit run /root/InternLM/Tutorial/tools/xtuner_streamlit_demo.py

埠對映之後再本地訪問:

ssh -CNg -L 8501:127.0.0.1:8501 root@ssh.intern-ai.org.cn -p 43551

3.2 指令跟隨微調

3.3 微調後

——————

目錄
  • 1. 基本概念
  • 2. 準備工作
    • 2.1 建立cuda12.2-conda的開發機
    • 2.2 環境準備
    • 2.3 安裝xtuner
    • 2.4 模型準備
  • 3. 快速開始
    • 3.1 微調前
    • 3.2 指令跟隨微調
    • 3.3 微調後
  • 1. 前置知識
  • 2. 環境、模型準備
    • 2.1 配置開發機環境
    • 2.2 安裝 Llamaindex
    • 2.3 下載 Sentence Transformer 模型
    • 2.4 下載 NLTK 相關資源
  • 3. LlamaIndex HuggingFaceLLM
  • 4. LlamaIndex RAG
  • 5. LlamaIndex web 圖形化介面

1. 前置知識

rag即檢索增強生成(Retrieval Augmented Generation,RAG。是在不改變模型權重的情況下對模型的生成式輸出進行一個改善。因為以對模型進行訓練的方式改變權重進而改變輸出的成本很高,所以rag的應用場景廣闊。
image
本次課程選用了LlamaIndex框架。LlamaIndex 是一個上下文增強的 LLM 框架,旨在透過將其與特定上下文資料集整合,增強大型語言模型(LLMs)的能力。它允許您構建應用程式,既利用 LLMs 的優勢,又融入您的私有或領域特定資訊。

2. 環境、模型準備

2.1 配置開發機環境

選擇映象 使用 Cuda11.7-conda 映象,然後在資源配置中,使用 30% A100 * 1 的選項,然後立即建立開發機器。

2.2 安裝 Llamaindex

進入開發機後,建立新的conda環境,命名為 llamaindex,在命令列模式下執行:
conda create -n llamaindex python=3.10
複製完成後,在本地檢視環境。
conda env list
image
執行 conda 命令,啟用 llamaindex 然後安裝相關基礎依賴 python 虛擬環境:
conda activate llamaindex
conda install pytorch2.0.1 torchvision0.15.2 torchaudio2.0.2 pytorch-cuda=11.7 -c pytorch -c nvidia
安裝python 依賴包
pip install einops
0.7.0 protobuf==5.26.1

安裝 Llamaindex和相關的包

conda activate llamaindex
pip install llama-index==0.10.38 llama-index-llms-huggingface==0.2.0 "transformers[torch]==4.41.1" "huggingface_hub[inference]==0.23.1" huggingface_hub==0.23.1 sentence-transformers==2.7.0 sentencepiece==0.2.0

2.3 下載 Sentence Transformer 模型

源詞向量模型 Sentence Transformer:(我們也可以選用別的開源詞向量模型來進行 Embedding,目前選用這個模型是相對輕量、支援中文且效果較好的,同學們可以自由嘗試別的開源詞向量模型) 執行以下指令,新建一個python檔案

cd ~
mkdir llamaindex_demo
mkdir model
cd llamaindex_demo
touch download_hf.py

開啟download_hf.py 貼入以下程式碼

import os

# 設定環境變數
os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'

# 下載模型
os.system('huggingface-cli download --resume-download sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 --local-dir /root/model/sentence-transformer')

執行程式碼
python download_hf.py

2.4 下載 NLTK 相關資源

我們在使用開源詞向量模型構建開源詞向量的時候,需要用到第三方庫 nltk 的一些資源。正常情況下,其會自動從網際網路上下載,但可能由於網路原因會導致下載中斷,此處我們可以從國內倉庫映象地址下載相關資源,儲存到伺服器上。 我們用以下命令下載 nltk 資源並解壓到伺服器上:

cd /root
git clone https://gitee.com/yzy0612/nltk_data.git  --branch gh-pages
cd nltk_data
mv packages/*  ./
cd tokenizers
unzip punkt.zip
cd ../taggers
unzip averaged_perceptron_tagger.zip

3. LlamaIndex HuggingFaceLLM

把 InternLM2 1.8B 軟連線出來
cd ~/model
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-1_8b/ ./

新建python檔案,執行模型

cd ~/llamaindex_demo
touch llamaindex_internlm.py
from llama_index.llms.huggingface import HuggingFaceLLM
from llama_index.core.llms import ChatMessage
llm = HuggingFaceLLM(
    model_name="/root/model/internlm2-chat-1_8b",
    tokenizer_name="/root/model/internlm2-chat-1_8b",
    model_kwargs={"trust_remote_code":True},
    tokenizer_kwargs={"trust_remote_code":True}
)

rsp = llm.chat(messages=[ChatMessage(content="博山廬是什麼?")])
print(rsp)

在命令列下執行模型:

conda activate llamaindex
cd ~/llamaindex_demo/
python llamaindex_internlm.py

結果為:
image
略通詩詞就知道明顯不對。據查證,白居易也沒有坐果博山廬,只作過廬山草堂記。

4. LlamaIndex RAG

安裝 LlamaIndex 詞嵌入向量依賴

conda activate llamaindex
pip install llama-index-embeddings-huggingface0.2.0 llama-index-embeddings-instructor0.1.3

為博山廬相關資訊在data資料夾建立一個boshanlu.md

一轉眼,我們自己的博山廬論壇一週年了,經歷了好多事,認識了好多小夥伴,也講了好多東西。甚至作了兩個系列的公開課。我們博山廬中人,這一年自己玩的很high,好多專案都是大家共同協作的Master piece. 原諒我這麼沒羞沒臊的表達。因為他們真的很棒。多才多藝,遠比我強多了。慢慢的各種人才都會多起來,大家互相磨礪,志氣出焉,我再也不是一個人前行。有你們在真的很好。
O(∩_∩)O哈哈~

自丁酉冬學以來,我們的語音課就沒停過。性自命出以及三字經九講,修書十二講(持續中),答疑不知多少回,立志課六講又是重頭戲,儒道隱逸十八講(正在進行中...),這就準備講桂巖子哈。是我們最喜歡春秋的一位同學主講。O(∩_∩)O哈哈~,然後各種文字整理,錄屏,影片製作組,都是協同工作,尤其《三字經》的兒童版我發現做的很精細,他們自出的《性命或問》收集了各種相關問題,當時乍一看真的很震撼,這些都是我們經歷的記錄。都是我們走過的路。我們可能會給剪輯成音訊,一切都在有條不紊的進行中。大家一邊複習,一邊都鬥閒煉己,一方面又是給後來者提供方便,學之為己,用之為人,誠哉斯言。我其實做的事,就是把東西拿出來講一遍,剩下基本所有的事,都不是我做的。說來蠻慚愧。而且現在回聽起來,很多地方都還是可以講的更清楚些,以後還得更努力,精益求精才對得起大家。

除了正經課程,我們還有各種娛樂好玩專案,過節就不知道過了幾次,昨晚就有深聊趴,還好把錄屏都刪除了。每次都笑的一塌糊塗是經常事。B站上的一人之下的乾貨影片作了五六個,還在繼續籌劃中、飲膳坊也在繼續進行中,慢慢的線下活動也多了起來,一起研討學問,一起運動,一起做手工,一起做飯,甚至博山宿舍都被提到日程上來,等等等等,太豐富了。回顧這一年來我們所走的路,達成的目標,遠比想象的豐富,而且都是我們沒有啥規劃的,悶頭做,不去想未來,專注於要做的事,結果回過頭來看,簡直有點目不暇接。這次要做個精選課堂影片,大家在剪輯精選問題的時候,發現我們真的講了好多事情,有好多資源了,都是大家一起打造的,但是因為我們不斷再講新的,所以沒來得及回顧,提煉,發酵。那就有點浪費了,還是重學為習,重習為修的為上。而且一下子消化不了,會使得大家壓力變大,所以我們從週年祭開始,後半年的工作主要就是複習整理已有的課程。幫助大家消化,給大家時間切實踐行,能夠做到身上才算可以,我們要給大家養成新的學習生活習慣的時間。這樣的話新朋友是來得及跟上我們腳步的。這次我們出了試卷,8月5號考試,這期間兩週我們會經常開復習課,答疑課,歡迎新老朋友參與。屆時提前一天會給大家通知,直接參與就可以了。

其實我們在形成一種生活模式,健康上進,不刺激慾望,努力學習,敢於任事,遠離碎片化閱讀,遠離無聊的惡趣味,做點好玩的事,做點有意義的事,叫自己不要那麼頹廢,還能弄明白點事情,叫自己別白來一場吧。^_^輕鬆,上進,務實,尚志就是我們的精神趣味。

我們週年祭有贏取八種T恤的各種專案的活動,大家仔細耐心看活動說明。我們特意做的很複雜,因為沒有耐心的人是學不了我們的方式。心氣不降,看啥都是粗糙,沒耐心的。大夏天能看進去,本身就是第一步的篩選。攢夠了體恤就有各種級別的獎勵哈。O(∩_∩)O哈哈~,我們可是把課程的盈餘都用啦哈,出書組的小夥伴強烈抗議,說是沒錢出書了,我們就自己印點好了。反正都是自己人再看。《砂金集》修訂本,裡面加了很多料。應該蠻好玩的,等到徹底弄好,就放出來,而且這些都是個紀念吧。二十後回首時,睹物思人,會心一笑,念念遠方,何時聚首?回顧所行,士心逾精,志氣愈純,再看看自己的正在伏案讀書的孩子,唸的正是我們博山廬的課程,也許就又有了無窮的動力和生機。去追尋遠方的友人。^_^

我們六件T恤分別是兩個系列,誠敬公,專序勤,兩件週年祭特別款是定志如山和破殼而出。^_^

那第一次看到我們的朋友,肯定會問博山廬是幹啥呢?是一幫什麼樣的人湊到一起的?這是一個版本的介紹,影片中沒用,但我覺得不用挺可惜,放在這裡吧:

華夏文明上溯古始,源頭在哪裡?又是怎麼流變的?中華文明要復興,根基在哪裡?我們的文明自信又源於何處?身為華夏子孫,我們應該怎麼去做,才能執古御今,以先王之學面對今時今日的各種挑戰?博山廬便是試圖回答這些問題的論學,切磋,踐行之所,這裡聚集著一群欲得自然之實、欲見天地之純、欲行先王之道的踐行者。

人以類聚,物以群分,同氣相求,同類相感,我們推廣我們的理念,是希望有同好能夠加入我們。

很多朋友都不願意和家人說清楚自己在學什麼,怕被誤會,那是因為沒人瞭解我們,社會環境中沒有我們的土壤,大家才會不好意思,或者擔心被誤解。其實先行開闢的人都會面臨這個問題。但只要你們真的變得更好,脾氣小了,身體變好了,做事積極了,敢於承擔,家人還會擔心嗎?一切以修身為本,忠恕之道啊。我們要是真的上進,健康,好學,儉樸,有禮,尚志,有啥丟人的嗎?為啥不敢說?為啥怕人知道?大家底氣應該足一些,沒有環境就創造環境,難道一直都避而不談嗎?所以不丟人,不用在意麵子,世間譭譽對志氣精純的人來說,不過就是清風拂面。若是怕這些,其實還是好名再作怪吧。若是有問題,不是學問的問題,而是我們做的不到家,那麼就不要怪罪別人,找別的原因,自己繼續調整就是了。^_^


我們應該是可以理直氣壯說出自己想要遵從華夏之道的一群人,為啥能夠如此?因為我們踐行,因為我們真的在用這個學問變得更好,因為我們尚志。士人尚志,志不是一個想法,而是行動精華的積累。我們就是想成為士人,不是一個美麗的幻想,不是一個口號,而是真的在行動。我們是由此登階而上,能見天地之純,能得自然之實,是踐行先王之學的華夏子孫。這不丟人,為啥不敢說出來?難道只有啃老宅男,鬼畜手淫,借款買房,荒淫遊戲,出口成髒,化妝弄醜,要當戲子,騙子上市,要掙多少錢是個小目標才在有勇氣說出來嘛?那種勢力,浮誇,頹廢,虛偽,拜金,自私,扭曲,殘忍,醜陋之極,也不過就是被泥巴糊住的人,他們表面的光鮮,自以為是的瀟灑背後是慾壑難填的空虛,焦慮,悔恨還有麻木不仁。這種風氣大行其道,是他們有問題,是這個世道有問題,而不是我們有問題。那些不過濁世的一片浪花。千百年後,半點也剩不下,而我們卻一直都在。

博山廬就是踐行傳播華夏先王之學,培養士人的地方,是給你們勇氣選擇善良的地方。

大家看,博山宿舍的小夥們今早穿上誠,敬,公,專,序,勤,準備出去游泳吃飯看電影哈。我和他們說,穿著這些衣服就不要駝著背,不要傲氣的抬著頭,不要扭七扭八的歪著,要身體中正,牢牢記住你們揹負的先王之道,不能辜負。


當你看到這個照片,覺得不好意思,覺得我們幼稚可笑,甚至鄙夷的時候,我們能理解,我們也是從那個階段過來的,這隻說明你暫時還不瞭解這些學問,現在還不是我們的同路人而已;當你覺得很不錯,也想穿的時候,自豪地穿在身上的時候,那你是真的嚮往,認可這個學問。我們從來都是雙向選擇的。嘿嘿。所以週年祭其實是一個問心踐行的考驗。你願意成士嗎?你願意踐行先王之道嗎?你願意見天地之純,得自然真實嗎?自己騙不了自己的。願意的朋友請認真參加我們的活動吧。裡面都是踐行的測試。不是為了獎勵,那些就是噱頭,為的是自己認識自己,藉著這個機會改變自己的陋習吧。

時空不過是隔絕不同德行存在的的名詞。夫子夢周公,漢墓壁畫上那些穿越時空的對飲並非幻想,我們一直都在。

先王仙聖與我們同在,萬世英靈與我們同在,後世諸聖與我們同在,天地風雷,自然造化與我們同在。雨師大人與我們同在。^_^

MAY THE DAO BE WITH US!

博山少年,前途似錦,來日方長,不可限量。大家看看我們一年下來做的事,就知道我們並非虛言。嘿嘿。我真的很開心哈。O(∩_∩)O哈哈~

emmmm,我覺得我還是應該去寫小說,^_^

建立一個新的python程式來讀取新加入的rag資訊:

cd ~/llamaindex_demo
touch llamaindex_RAG.py

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings

from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.llms.huggingface import HuggingFaceLLM

#初始化一個HuggingFaceEmbedding物件,用於將文字轉換為向量表示
embed_model = HuggingFaceEmbedding(
#指定了一個預訓練的sentence-transformer模型的路徑
    model_name="/root/model/sentence-transformer"
)
#將建立的嵌入模型賦值給全域性設定的embed_model屬性,
#這樣在後續的索引構建過程中就會使用這個模型。
Settings.embed_model = embed_model

llm = HuggingFaceLLM(
    model_name="/root/model/internlm2-chat-1_8b",
    tokenizer_name="/root/model/internlm2-chat-1_8b",
    model_kwargs={"trust_remote_code":True},
    tokenizer_kwargs={"trust_remote_code":True}
)
#設定全域性的llm屬性,這樣在索引查詢時會使用這個模型。
Settings.llm = llm

#從指定目錄讀取所有文件,並載入資料到記憶體中
documents = SimpleDirectoryReader("/root/llamaindex_demo/data").load_data()
#建立一個VectorStoreIndex,並使用之前載入的文件來構建索引。
# 此索引將文件轉換為向量,並儲存這些向量以便於快速檢索。
index = VectorStoreIndex.from_documents(documents)
# 建立一個查詢引擎,這個引擎可以接收查詢並返回相關文件的響應。
query_engine = index.as_query_engine()
response = query_engine.query("博山廬是什麼?")

print(response)

執行程式碼測試結果:

conda activate llamaindex
cd ~/llamaindex_demo/
python llamaindex_RAG.py

image

5. LlamaIndex web 圖形化介面

//todo
在補充資料之前:

在補充資料之後:

相關文章