3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LLMバッチ推論によるドキュメントサイトのメンテナンス効率化

Posted at

書くのを少し迷いましたが、ユースケースとしては有用だと思いましたのでこちらにまとめます。

LLMバッチ推論とは

大量のテキストに対してLLMをバッチ処理で適用して、効率改善などビジネス上の課題を解決します。

適用条件

  • テキストが大量にある
  • 処理内容がLLMに適している(要約、情報抽出、翻訳、内容チェックなど)

適用事例

背景

Databricksの日本語マニュアルは英語からの機械翻訳がベースとなっています。私を含めて日本人のエンジニア数名でチェックはしているのですが、どうしてもチェック漏れが発生していました。以下の画像のように、英単語があると語順がおかしくなるケースが散見されていました。

Screenshot 2025-04-22 at 9.38.51.png

新たに翻訳されたページの連絡はもらっているものの、すべてのページの目検をやり続けるには限界があります。

アプローチ

  • マニュアルページの一覧はサイトマップとして公開されているので、これをクローリングしてDeltaテーブル化します。このテーブルに対してLLMバッチ推論で一括でチェックするようにしました。
  • プロンプトは以下の通りです。判定結果だけでなく、理由も出すように指示しています。

あなたは日本語が流暢なDatabricksの専門家です。右のDatabrickマニュアルを確認します。日本語としておかしい箇所、特に語順の間違いに注意してください。「SDKDatabricksOAuth」のような空白を含まない英語の羅列に注意してください。語順がおかしい可能性が高いです。固有名詞が英語のままであることは許容しますが、一般用語の翻訳漏れにも注意してください。全体的に日本語としての品質が低い場合にはNG、問題がなければOKを返してください:

  • 判定結果はダッシュボードで確認できるようにしました。

実装

サービングエンドポイントの準備

LLMバッチ推論では高いスループットが必要になるので、Provisioned Throughput(毎回翻訳を悩むのですが、スループット配備済みとかなんですかね。要ははスループット保証型です)のモデルサービングエンドポイントを使っています。モデルはLlama 3.1 405b instructです。

Screenshot 2025-05-02 at 15.30.56.png

ノートブック

%pip install bs4 lxml
%restart_python
import requests
from bs4 import BeautifulSoup

def extract_title_and_contents(url):
  response = requests.get(url)
  soup = BeautifulSoup(response.content.decode("utf-8", "ignore"), 'html.parser')

  # 更新時刻
  last_modified = soup.find('time').get_text()

  # タイトル
  title = soup.find('title').get_text()
  # 本文
  contents = soup.find('div', class_="theme-doc-markdown markdown").get_text()

  return title, contents, last_modified

クローリング

import requests
from bs4 import BeautifulSoup

# 指定されたURL
sitemap_url = "https://docs.databricks.com/aws/ja/sitemap.xml"

# URLの内容を取得
response = requests.get(sitemap_url)
soup = BeautifulSoup(response.content, "lxml-xml")

# URLを抽出
urls = [loc.text for loc in soup.find_all("loc")]

doc_pages = []
count = 0

# 抽出されたURLを表示
for url in urls:

    # 除外
    # https://docs.databricks.com/aws/ja/release-notes/
    # https://docs.databricks.com/aws/ja/sql/language-manual/
    # https://docs.databricks.com/aws/ja/error-messages/

    if (
        url.startswith("https://docs.databricks.com/aws/ja/release-notes/")
        or url.startswith("https://docs.databricks.com/aws/ja/sql/language-manual/")
        or url.startswith("https://docs.databricks.com/aws/ja/error-messages/")
    ):
        continue

    print(url)
    title, contents, last_modified = extract_title_and_contents(url)
    doc_pages.append((url, title, contents, last_modified))

    count = count + 1

Deltaテーブルに保存

import pyspark.sql.functions as f
import pyspark.sql.types as T
from pyspark.sql.types import TimestampType

df = spark.createDataFrame(
    doc_pages,
    "url string, title string, contents string, last_modified string"
).withColumn("last_modified", f.to_timestamp("last_modified", "yyyy年M月d日"))

display(df)

Screenshot 2025-05-02 at 15.30.03.png

df.write.mode("overwrite").saveAsTable("takaakiyayoi_catalog.doc_maintenance.databricks_docs")

LLMバッチ推論

ai_query関数を使うことで、SQLから直接LLMにアクセスできます。出力を構造化するようにresponseFormatを指定しています。

%sql
INSERT INTO takaakiyayoi_catalog.doc_maintenance.databricks_doc_judge_result
SELECT *,
  ai_query(
    'taka-llama-pt',
    "あなたは日本語が流暢なDatabricksの専門家です。右のDatabrickマニュアルを確認します。日本語としておかしい箇所、特に語順の間違いに注意してください。「SDKDatabricksOAuth」のような空白を含まない英語の羅列に注意してください。語順がおかしい可能性が高いです。固有名詞が英語のままであることは許容しますが、一般用語の翻訳漏れにも注意してください。全体的に日本語としての品質が低い場合にはNG、問題がなければOKを返してください: " || contents,
    responseFormat => 'STRUCT<doc_judge:STRUCT<result:STRING, explanation:STRING>>'

    ) AS judge_result,
  current_date() AS processed_date
  FROM takaakiyayoi_catalog.doc_maintenance.databricks_docs

実行結果にはOKかNGの判定結果、そして判定理由が含まれています。

Screenshot 2025-05-02 at 15.36.19.png

ジョブの設定

ノートブックとダッシュボードを組み合わせます。

Screenshot 2025-05-02 at 15.37.26.png

ダッシュボード

判定結果の時系列変化と、最新の判定結果を確認できるようにしています。

Screenshot 2025-05-02 at 15.38.02.png

以下のように判定結果のJSONは直接読み込むことができますので、ダッシュボードへの繋ぎ込みも楽です。

SELECT
  *,
  judge_result:result AS OK_NG,
  judge_result:explanation AS REASON
FROM
  takaakiyayoi_catalog.doc_maintenance.databricks_doc_judge_result
WHERE
  processed_date = (
    SELECT
      MAX(processed_date)
    FROM
      takaakiyayoi_catalog.doc_maintenance.databricks_doc_judge_result
  )

まとめ

  • LLMバッチ推論は簡単にジョブに組み込めるので、内容チェックからダッシュボードの可視化まで自動化できます。
  • バッチ処置では、複数の値(今回の例なら判定結果と理由)を返却するように指示できるので、後段で柔軟な処理が可能です。
  • Databricksにはスループット保証のAPIがあるので、高速にバッチ処理を行うことができます。

効率化しつつも、引き続きドキュメントの品質改善に努めてまいります。今後は複数観点(内容の平易さなど)でのチェックも組み込みたいと考えています。

はじめてのDatabricks

はじめてのDatabricks

Databricks無料トライアル

Databricks無料トライアル

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?