ゼロからはじめる:金倉コミュニティデータを活用したLoRa、微細調整とSpring AIによるプライベートQwenモデル構築

はじめに

前回のCozeプラットフォームでの金倉向け解決アシスタント構築では、HTTPインターフェースを通じて金倉プラットフォーム内の検索を行い、大モデルの推論能力を活用してユーザーへの回答を提供していました。しかし、金倉内部の検索機能には明らかに限界がありました。検索でヒットした博文資料間の関連性が希薄であり、智能体が回答を作成する際に大量の長文資料を参照する必要があり、特に数万字に及ぶ内容を検索せざるを得ない場合があり、全体的な効率に大きく影響していました。

この課題に対応するため、本記事では智能体の回答精度と効率を向上させる手法を説明します。本質的な問題は、既存の資料をどのように効率的に活用して推論と回答を行うかにあります。金倉コミュニティの検索メカニズムを直接変更することは不可能ですが、間接的なアプローチを採用できます:事前にコミュニティで公開されているドキュメントや博文を検索し、これらのコンテンツに基づいて既存の大モデルを微細調整のです。この方法により、大モデルはユーザーからの質問itoba efficiently既知的信息を活用し、より正確な回答を提供でき、直接的な検索最適化と同様の効果を実現できます。

本日の目標

本日のメインターゲットは、既存の資料を活用したQwen2.5-7B-InstructオープンソースモデルのLoRa微細調整です。金倉コミュニティにはこのモデルに関する豊富な博文とドキュメントがあるため、本稿では特定の分野に焦点を当てます。データベース移行方面的トレーニングに注力し、ネットワーク接続がない環境でも有効な知識検索と処理能力を持つモデルの構築を目指します。

LoRa技術とは

智能体(AI)技術はすでに日常生活に広く浸透し、人々の間で一般的な理解を得ています。しかし、現行の大規模言語モデルの微細調整技術は真正のの普及に至っていません。その主な理由は、高い雰囲门槛にあります。まず、大モデルの微細調整には高性能サーバーやGPUなどの強力な計算リソースが必要であり、さらには様々な複雑なパラメータ設定などの技術的課題も解決する必要があります。これは多くの企業や個人にとって大きな負担となっています。

此外、从零开始训练一个大模型所需的资源和成本也是一般公司难以承担的。因此,目前广泛采用的策略是基于已有的预训练模型进行再训练(fine-tuning)。这种方法充分利用了现有大模型的基础架构,再加上企业内部的专有数据进行定制化调整,能够大大降低训练成本并提高模型的适应性和效率。LoRa(Low-Rank Adaptation)技術,企业能够在不重新训练整个模型的情况下,针对特定任务进行快速微调を実現します。

環境準備

計算リソースの準備

資料庫データを用いた微細調整を行うには、十分な準備が必要です。まず、内部資料データの準備が必要であり、データの品質と多様性を確保し、必要なビジネスシナリオや問題をカバーする必要があります。次に、GPUを搭载したサーバーを用意し大量のデータを処理し、深度学習モデルのトレーニングと最適化を支える十分な計算能力を確保する必要があります。

資料収集

データベース移行問題の解決策に関するトレーニングに注力するため、金倉コミュニティに直接アクセスしてデータベース移行関連の最新データとドキュメントを取得しました。以下の図に示す手順で行いました:

ドキュメントダウンロード

関連するドキュメントやライブラリをダウンロードし、以下の図のような操作手順で実行しました:

さらに、博客やフォーラムなどのオンラインリソースも資料源となります。スパイダーで直接取得も可能ですが、コミュニティサーバーに過度の負荷をかけないよう、関連するデータを直接ローカルに保存し、その後解析して情報を抽出する方法を採用しました。以下の図を参照してください:

指示データセットの構築

基本的なデータを取得した後は、后续処理と分析のために必要なデータセット形式に解析する必要があります。LLM(大言語モデル)の微細調整は、通常、指示微細調整プロセスです。所谓指示微細調整とは、特定のフォーマットの微細調整データを通じて、モデルに特定の指示に対する响应方法を学習させることです。 这些微細調整データの典型的な構造と形式は以下の通りです:

[{
    "instruction": "KESとは?",
    "input": "",
    "output": "KESは人大金倉の略称です。"
}]

ここで、instructionはユーザーにタスクを通知し、inputはユーザーの指示を完了するために必要な入力内容、outputはモデルが提示すべき出力です。

目標フォーマット既然已经获得のデータが手元にあるため、次に行うべきことはこれらのドキュメントを解析することです。为此、Spring AIを採用します。Spring AIはPDF、HTML、Markdown、JSON、Docxなど複数のファイル形式の解析をサポートします。現在扱っているドキュメントフォーマットはPDFとHTMLのみのため、Spring AIは十分なニーズを満たしています。

ドキュメント抽出

まず、新しいSpring Bootプロジェクトを作成し、项目に导入する必要のある相關依存関係を追加します。プロジェクトの基本構造は以下の通りです:

次に、プロジェクトのPOM依存関係を导入し、関係するライブラリとツールが正しく加载できるよう 确保します。具体的な依存関係は以下の通りです:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/>
    </parent>

    <artifactId>02-example-RAG-backend</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <knife4j-version>4.1.0</knife4j-version>
        <hutool-version>5.8.2</hutool-version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>1.0.0-M8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
            <version>${knife4j-version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-tika-document-reader</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-pdf-document-reader</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-jsoup-document-reader</artifactId>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-openai</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

здесь мы вводим текущую версию M8 Spring AI и связанные с OpenAI интерфейсы модели。这是因为文档提取完成后、提取したデータを解析して指示セットフォーマットに変換する必要があります。AIを活用することで、従来のを手作业によるデータクリーニング工作量大幅削减できます。또한、関連するモデルインターフェース配套のシークレット設定情報を导入し、システムがこれらのサービスにアクセスして使用できるようにします。具体的な設定は以下の通りです:

server.port=9166
spring.ai.openai.base-url=
spring.ai.openai.api-key=
spring.ai.openai.chat.options.model=

здесь в основном настраивается информация об интерфейсе OpenAI. Если у вас нет доступа к иностранным API, большинство отечественных больших моделей также совместимы с этой конфигурацией интерфейса, вы можете напрямую ввести соответствующий интерфейс отечественной большой модели, и он также может быть успешно вызван.

次に、Spring AIのドキュメント抽出器を使用したドキュメント解析の具体的な実装コードは以下の通りです:

public List<Document> extractDocsFromHTML() throws IOException {
    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(resourceLoader);
    org.springframework.core.io.Resource[] resourceArray = resolver.getResources("classpath:/file/*.html");

    List<Document> documentList = Arrays.stream(resourceArray)
            .flatMap(resource -> {
                JsoupDocumentReader reader = new JsoupDocumentReader(resource,
                        JsoupDocumentReaderConfig.builder()
                                .selector("p")
                                .charset("UTF-8")
                                .build());
                return reader.get().stream();
            })
            .collect(Collectors.toList());
    return documentList;
}

здесь в основном описывается, как извлечь текстовое содержимое из HTML-файлов. 由于下载したHTMLファイルには通常、さまざまなスタイル、スクリプト、およびその他の関係のない情報が含まれているため、テキスト段落部分である`

`タグ内のテキストコンテンツのみに焦点を当てます。この,他还讨论了如何从PDFドキュメントからテキストを抽出する具体的な实现如下:

public List<Document> extractDocsFromPDF() throws IOException {
    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(resourceLoader);
    org.springframework.core.io.Resource[] resourceArray = resolver.getResources("classpath:/file/*.{pdf,PDF,Pdf}");

    List<Document> documentList = Arrays.stream(resourceArray)
            .filter(resource -> resource.getFilename() != null &&
                    resource.getFilename().toLowerCase().endsWith(".pdf"))
            .flatMap(resource -> {
                System.out.println("ファイル名:" + resource.getFilename());
                try {
                    ParagraphPdfDocumentReader pdfReader = new ParagraphPdfDocumentReader(resource,
                            PdfDocumentReaderConfig.builder()
                                    .withPageTopMargin(0)
                                    .withPageExtractedTextFormatter(ExtractedTextFormatter.builder()
                                            .withNumberOfTopTextLinesToDelete(0)
                                            .build())
                                    .withPagesPerDocument(1)
                                    .build());
                    return pdfReader.read().stream();
                }catch (Exception e){
                    PagePdfDocumentReader pdfReader = new PagePdfDocumentReader(resource,
                            PdfDocumentReaderConfig.builder()
                                    .withPageTopMargin(0)
                                    .withPageExtractedTextFormatter(ExtractedTextFormatter.builder()
                                            .withNumberOfTopTextLinesToDelete(0)
                                            .build())
                                    .withPagesPerDocument(2)
                                    .build());
                    return pdfReader.read().stream();
                }
            })
            .collect(Collectors.toList());
    return documentList;
}

テキスト抽出的过程中、将其分为两种不同的格式进行处理しました。第一种是使用`ParagraphPdfDocumentReader`クラスを使用し、これはディレクトリ付きのPDFファイルを抽出し、ディレクトリの内容に基づいてバッチ抽出を行うことができます。もう一方はディレクトリのないPDF文件的处理で、現在は`PagePdfDocumentReader`クラスを使用し、ページ数に基づいてPDFファイルのページごとのテキスト抽出を行います。

いずれかの方法でテキストを抽出すると、最終的に抽出されたコンテンツは自動的にベクトルデータベース存储に最適化された`Document`フォーマットにカプセル化されます。この过程中では、テキストコンテンツのみ的关注し其他的コンテンツは無視されるため、AI效率的の抽出が確保されます。具体的なコード実装は以下の通りです:

public List<InputData> processHTMLContent() throws IOException {
    List<Document> docsFromHTML = extractDocsFromHTML();
    TokenTextSplitter splitter = new TokenTextSplitter();
    List<Document> documentList = splitter.apply(docsFromHTML);

    List<Future<List<InputData>>> futures = documentList.stream()
            .map(doc -> executorService.submit(() -> analyzeDocument(doc).toList()))
            .collect(Collectors.toList());

    List<InputData> results = new ArrayList<>();
    for (Future<List<InputData>> future : futures) {
        try {
            results.addAll(future.get());
        } catch (Exception e) {
            log.error("Error processing document in thread: {}", e.getMessage());
        }
    }
    return results;
}

HTML抽出後の各博文やドキュメントには大量のテキストが含まれているため、`TokenTextSplitter`クラスを使用して抽出したテキストを分割する必要があります。分割されたテキストは、より効率的に处理するために多个小块に分割されます。処理速度を向上させるために、本文ではスレッドプールを採用し、AIが並行してドキュメントを быстро解析できるようにしています。具体的なコード実装は以下の通りです:

private Stream<InputData> analyzeDocument(Document document) {
  String jsonStr = document.getText();
  log.info("Processing document content: {}", jsonStr.length() > 100 ? jsonStr.substring(0, 100) : jsonStr);

  try {
      List<InputData> dataList = chatClient.prompt()
              .system("""
                  - 役割: データクリーニング専門家および情報抽出エンジニア
                  - 背景: ユーザーはKES人大金倉の移行相关内容のドキュメントシリーズから关键情報を抽出する必要がありますが、ドキュメントには大量の関係のないコンテンツが含まれており、効率的な筛选が必要です。
                  - プロファイル: あなたは海量のテキストから关键情報を抽出することに擅长する経験豊富なデータクリーニング専門家であり、KES人大金倉移行に関連する知识点、注意点、実践経験を正確に識別する強力なテキスト分析能力と情報筛选能力を持っています。
                  - スキル: 自然言語処理技術、テキストマイニング方法、情報筛选戦略を専門とし、ドキュメントから关键コンテンツを素早く特定して抽出すると同時に、无関係な情報を除外できます。
                  - 目標: ユーザー提供のドキュメントからKES人大金倉移行に関連する注意点、知识点、実践経験を抽出し、无関係なコンテンツを削除し、抽出された情報が正確で完全であることを确保します。
                  - 制約: 抽出された情報は简洁明了で冗長性を避け、KES人大金倉移行に直接関連する必要があります。無関係なコンテンツを含むことは禁止されています。本文、现场获取などの表現出现を避けるべきです。
                  - 出力フォーマット: 知识点、注意点、実践経験の分類整理を含む構造化された形式で关键情報を出力します。
                  - ワークフロー:
                    1. ユーザーが提供するドキュメントを注意深く読み、ドキュメントの全体的な內容と構造を理解します。
                    2. 「移行注意点」「KES知识点」「移行実践」など、KES人大金倉移行に関連するキーワードとテーマを特定します。
                    3. テキスト分析技術を応用し、これらのキーワードとテーマに関連するコンテンツをドキュメントから抽出し、无関係な情報を除外します。
                    4. 抽出したコンテンツを分類整理し、構造化された出力を形成します。
                    5. instructionが質問で、inputが固定で""、outputが回答で、回答テキストは200〜400文字の範囲でMarkdown形式である必要があります。
                  - 例:
                      [{
                          "instruction": "KESとは?",
                          "input": "",
                          "output": "KESは人大金倉の略称です。"
                      }]
                  """)
              .user(jsonStr)
              .options(ChatOptions.builder().temperature(0.8).build())
              .call()
              .entity(new ParameterizedTypeReference<List<InputData>>() {});

      log.info("dataList size: {}", dataList != null ? dataList.size() : 0);
      return dataList == null ? Stream.empty() : dataList.stream();
  } catch (Exception e) {
      log.error("Error processing document: {}", ExceptionUtil.stacktraceToString(e));
      return Stream.empty();
  }
}

単純なプロンプトを使用してAIにまとめと归纳,引导其生成一系列指示数据集。最后,利用構造化出力将这些指示封装成具体的类,以便进一步使用和管理します。具体的な実装コードは以下の通りです:

public record InputData(String instruction, String input, String output) {}

最后,我们将処理后的数组以JSON格式写入文件中,基本的な流程就此完成。接下来,我们可以查看最终的提取效果,具体效果如图所示:

総合的に见ると、データセット全体のパフォーマンスはまもなくですが、プロンプトはさらに最適化する必要があります。最終的な生成されたデータセットの规模は振るわず、効果的なトレーニング基本上できない数百件のみでした。全体の効果を示すために、同じドキュメントを複数回実行し、2000以上のデータサンプルを集めました。ただし、このようなアプローチには確かにいくつかの問題があります。そのため、時間的余裕があれば、より多くの文献や资料をダウンロードして、データセットの質と规模,确保支持更好的トレーニング效果应该更好です。

サーバー準備

次に、指示セットの解析後、大モデルの微細調整を行う必要があります。まず、20GB以上のGPUメモリを持つサーバーを確保していることを確認してください。ない場合は、クラウドでレンタルすることを検討できます。ここではAutoDL AI算力云を使用しており、具体的な詳細については省略します。

微細調整の経験がない場合は、ゼロから学ぶことをお勧めします。个人的には、オープンソースプロジェクトで経験を积累しました。オープンソースプロジェクトの 地址は以下の通りです:https://github.com/datawhalechina/self-llm

微細調整

次に、サーバーをレンタルし、環境の依存関係はコミュニティが提供するイメージを直接使用できます。オープンソースプロジェクトも関連するイメージを提供しておりニーズに合わせて作成できます。最終的な設定は下の図のようです:

次に、JupyterLabを使用してサーバーに素早く接続します,如图所示:

使用したイメージはQwen2.5から引っ張ったものであり、このイメージにはオープンソースプロジェクトに必要なすべてのファイルとディレクトリが含まれています。如图所示:

次に、データセットを指定された位置にアップロードし、必要に応じて関連するファイルディレクトリの設定を調整するだけで、具体的な操作步骤は以下の通りです:

コードは 간단하게データセット地址を変更するだけで済み、データセットには複数のJSONファイルが含まれているため、すべてのファイルを加载した後にマージする必要があります。修改後のコードは以下の通りです:

import os
import glob
import pandas as pd
from datasets import Dataset

# ディレクトリパスを設定
directory_path = 'kes'

# ディレクトリ下のすべてのJSONファイルを取得
json_files = glob.glob(os.path.join(directory_path, '*.json'))

# 加载されたすべてのJSONデータを存储
all_data = []

# すべてのJSONファイルを遍历してロード
for json_file in json_files:
    print(f"加载中: {json_file}")
    df = pd.read_json(json_file)
    all_data.append(df)

# すべてのDataFrameをマージ
combined_df = pd.concat(all_data, ignore_index=True)

# DataFrameをHugging Face Datasetに変換
ds = Dataset.from_pandas(combined_df)

関連する指示を変更する際主な変更点は、システムプロンプトを「金倉アシスタント」に変更することです。具体的な変更内容は以下の通りです:

def process_func(example):
    MAX_LENGTH = 384
    input_ids, attention_mask, labels = [], [], []
    instruction = tokenizer(f"<|im_start|>system\n今你是金倉のアシスタント<|im_end|>\n<|im_start|>user\n{example['instruction'] + example['input']}<|im_end|>\n<|im_start|>assistant\n", add_special_tokens=False)
    ## 省略重复コード

次に、微細調整トレーニングプロセスに入ります、具体的な步骤は以下の通りです:

全体的なプロセスは約10分程度の時間を费やす必要があり、データセットの规模がまだ比较的小さいことを考えると、処理速度は遅くないでしょう。

効果 демонстрация

最后、トレーニング完成后、LoRa微細調整の効果を確認するための 간단한テストを行います。以下は関連するコード実装です:

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
from peft import PeftModel

mode_path = '/root/autodl-tmp/qwen/Qwen2.5-7B-Instruct/'
lora_path = './output/Qwen2.5_instruct_lora/checkpoint-450'

tokenizer = AutoTokenizer.from_pretrained(mode_path, trust_remote_code=True)

model = AutoModelForCausalLM.from_pretrained(mode_path, device_map="auto",torch_dtype=torch.bfloat16, trust_remote_code=True).eval()

model = PeftModel.from_pretrained(model, model_id=lora_path)
prompt = "KESデータ移行ツールKDTSは哪些ソースデータベースの移行をサポートしていますか?"
inputs = tokenizer.apply_chat_template([{"role": "system", "content": "假设你是金倉のアシスタントです。"},{"role": "user", "content": prompt}],
                                       add_generation_prompt=True,
                                       tokenize=True,
                                       return_tensors="pt",
                                       return_dict=True
                                       ).to('cuda')


gen_kwargs = {"max_length": 2500, "do_sample": True, "top_k": 1}
with torch.no_grad():
    outputs = model.generate(**inputs, **gen_kwargs)
    outputs = outputs[:, inputs['input_ids'].shape[1]:]
    print(tokenizer.decode(outputs[0], skip_special_tokens=True))

現在、LoRaの重みはまだ基础モデルとマージされておらず、模型にロードされただけです。ここでは、ロード後の効果とLoRa重みの役割を確認するための簡単なテストを行い、出力は以下の通りです:

Oracle、MySQL、SQLServer、Gbase、PostgreSQL、DM、KingbaseESなどのデータベースがサポートされています。これらのデータベースバージョンはすべてサポート範囲に含まれており、移行プロセス中の互換性と安定性が确保されています。

可视化されたWEBページを露出させてアクセスできるようにしたい場合、まず配置ファイルの要件に従って操作する必要があります。具体的な步骤は次の通りです:という名前の新しいファイルを作成し、そこに以下の内容を記述します:

from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
import streamlit as st
from peft import PeftModel

with st.sidebar:
    st.markdown("## Qwen2.5 LLM")
    "[オープンソース大モデル食用ガイド self-llm](https://github.com/datawhalechina/self-llm.git)"
    max_length = st.slider("max_length", 0, 8192, 512, step=1)

st.title("💬 Qwen2.5 Chatbot")
st.caption("🚀 Self-LLM搭載のストリームリットチャットボット")

@st.cache_resource
def get_model():
    mode_path = '/root/autodl-tmp/qwen/Qwen2.5-7B-Instruct/'
    lora_path = '/root/output/Qwen2.5_instruct_lora/checkpoint-450'
    
    tokenizer = AutoTokenizer.from_pretrained(mode_path, trust_remote_code=True)
    tokenizer.pad_token = tokenizer.eos_token
    model = AutoModelForCausalLM.from_pretrained(mode_path, device_map="auto",torch_dtype=torch.bfloat16, trust_remote_code=True).eval()
    
    model = PeftModel.from_pretrained(model, model_id=lora_path)
    return tokenizer, model

tokenizer, model = get_model()

if "messages" not in st.session_state:
    st.session_state["messages"] = [{"role": "system", "content": "假设你是金倉のアシスタントです。"},{"role": "assistant", "content": "私は金倉アシスタントです。何かお手伝いできることはありますか?"}]

for msg in st.session_state.messages:
    st.chat_message(msg["role"]).write(msg["content"])

if prompt := st.chat_input():
    st.chat_message("user").write(prompt)
    st.session_state.messages.append({"role": "user", "content": prompt})

    input_ids = tokenizer.apply_chat_template(st.session_state.messages,tokenize=False,add_generation_prompt=True)
    model_inputs = tokenizer([input_ids], return_tensors="pt").to('cuda')
    generated_ids = model.generate(model_inputs.input_ids,max_new_tokens=max_length)
    generated_ids = [
        output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
    ]
    response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]

    st.session_state.messages.append({"role": "assistant", "content": response})
    st.chat_message("assistant").write(response)

オープンソースプロジェクトに基づいて、カスタマイズ改建を行い、主にチェックポイントやシステムプロンプトなどのパラメータの調整。最后、次のようなコマンドラインでシステムを起動します:

streamlit run /root/autodl-tmp/chatBot.py --server.address 127.0.0.1 --server.port 6006

次に、算力云提供的操作步骤に従って、関連する設定と操作を逐步的に行います。各ステップはガイドに严格に従って执行し,以确保配置と启动顺利完成,具体流程见下图:

командная строка形式で效果を表現しており、具体的な状況は下のスクリーンショットを参照してください:

вышеупомянутых шагов успешно выполнены. Далее мы можем 直接 получить доступ к локальному порту 6006, адрес доступа: http://localhost:6006, и войти в соответствующий интерфейс для дальнейших операций.

Base Modelとの比較は行っていないなぜ냐하면、その効果はLoRa微調整後明らかに劣っているためです。より適切な比較のために、私が常用するKimiモデルを選択しました。比較を通じて、ネットワーク接続がない情况では、特定の知識のパフォーマンスが微調整後の效果不如であることが 확실합니다。しかしながら、微調整に使用したデータセットの範囲が比較的に狭いため、過学習がある程度発生しました。しかし、全体的に見ると微調整プロセスは大概この通りに展开されます。

しかし、微調整後の効果は比較的満足のいくものであり、智能体がコミュニティを検索する方法と比較して、応答速度が明らかに向上し、レスポンス時間が速くなります。同時に、tokenのコストも大幅に削減されました。より重要なのは、微調整後のモデルは完全に私有化配置できることであり、このように企业内部のデータの安全性が确保され、データ漏洩の問題を心配する必要がありません。

まとめ

本次关于金倉迁移相关的微细调整文章就到此结束。我们不仅成功解决了金倉平台中検索機能导致智能体响应慢的问题,还有效控制了token费用的高昂支出。在这个过程中,我们通过利用现有的文档和博文,对大模型进行了微细调整。通过提前检索和处理金倉社区的相关资料,微细调整后的大模型能够在没有网络连接的环境下,依靠更加精确的知识库进行问题解答,从而弥补了原有検索メカニズム的不足之处。

微细调整过程中,尽管我们面临了许多挑战,例如文档データの整理と抽出、指示セットの構築などの问题ですが、Spring AIなどのフレームワークツールを活用することで、構造化されていないドキュメントデータを構造化情報に変換し、微细调整プロセスの順調な進行を確保しました。最终的に、モデルの私有化配置を実現し、Streamlitを使用した可视化的展示と配置を行い、微细调整环节を圆满に完了しました。この共有が皆様のご作業と研究にある程度の帮助と启发をもたらすことを幸いです!

タグ: LoRa Spring AI Qwen 微細調整 データベース移行

5月11日 22:06 投稿