翻訳に特化したLLM

翻訳機能が欲しくていくつか試していました。
1)正しく翻訳できること。
2)文法的に間違いの無い日本語になること
3)余計な考察は行わないこと
4)翻訳の速度が早いこと

モデル

多くは試せないので、過去に実績のあるモデルを試しました。

変換速度
LLMの生成速度(=Token/secが大きい)のことになります。
 Ctranslate版が最も早い
 gguf版が次
 量子化版
のような感じです。

正確性
定義づけ難しいのですが、意訳をしたり、端折ったり、余分な文章を付けたしないことですね。直訳でも困るので正しい日本語になっていることも大事かなと思います。

1)rinna-4btのCtranslate版
2)rinna-yuurシリーズのgguf版
3)stabilityaiのjapanese-stablelm-instruct-gamma-7bのgguf版
結果は以下のような感じでした。4060クラスのGPUです。3080クラスだとjapanese-stablelm-instruct-gamma-7bのgguf版でも2.5秒程度です。

1)はかなり省略してしまいます。要約でもなく、まさに省略。長文は苦手
2)はなかなかいい感じで、変換速度も早いのですが、1)と同様に長文は省略が目立ちます。q3 だと省略は軽減されるが傾向は同じです。
3)は元々日本語能力が高く、汎用で使っても良い感じです。ただし、余計なこといっぱい出して来ます。チャットだと逆らうことも有ったりですね。この傾向は翻訳でも同じですが、temperature=0.0とすることで、ほぼ防げるような感じです。あとは、ggufのどのモデルにするかですが、Qの数字の大きいほうが正確で小さいほうがモデルも小さいのですが、正確性が徐々に低下します。
変換速度と正確性のバランス考えると、Q3-K-Mが最適のようです。
(私の環境では)
temperature=0.0でないと、時々省略します。0.0だと毎回同じ回答ですがやや硬い感じ。少し上げても良いかもです。

サーバ側
例のようにFastAPIでラップした、サーバにしています。llama.cppが動く環境で実行します。

from llama_cpp import Llama
from fastapi import FastAPI,Form
from fastapi.responses import HTMLResponse
from pydantic import BaseModel

# LLMの準備 #llm  = Llama(model_path="./models/japanese-stablelm-instruct-gamma-7b.Q2_K.gguf",
#               n_gpu_layers=35,
#               n_ctx=2048
#                 ) #llm  = Llama(model_path="./models/japanese-stablelm-instruct-gamma-7b.Q3_K_M.gguf",
#               n_gpu_layers=35,
#               n_ctx=2048
#                 )
llm = Llama(model_path="./models/rinna-youri-7b-instruction-q3_K_M.gguf",
               n_gpu_layers=35,
               n_ctx=2048
                 ) #lm  = Llama(model_path="./models/rinna-youri-7b-instruction-q2_K.gguf",
#               n_gpu_layers=35,
#               n_ctx=2048
#                 ) #llm  = Llama(model_path="./models/japanese-stablelm-instruct-gamma-7b.Q8_0.gguf",
#               n_gpu_layers=35,
#              n_ctx=2048
#                 )
app = FastAPI()

class AnswerRequest(BaseModel):
     sys_msg : str
     user_query:str
     user:str
     max_token:int
     temperature:float 

@app.post("/generate/")
def  genereate(gen_request: AnswerRequest):
    sys_msg       =gen_request.sys_msg
    user_query =gen_request.user_query
    user                 =gen_request.user
    max_token =gen_request.max_token
    get_temperature=gen_request.temperature

    prompt = sys_msg+"\n\n" + "### 指示: "+"\n" + user_query + "\n\n"  +  "### 入力:" +"\n"+ user + "\n\n"  +  "### 応答:"
    # 推論の実行
    output = llm(
        prompt,
        max_tokens=max_token,
        temperature=get_temperature,
        top_k=40,
        stop=['"### 入力"'],
        repeat_penalty=1,
        echo=True,
        )
    #output  の"### 応答:"のあとに、"###"がない場合もあるので、ない場合は最初の"### 応答:"を選択
    try:
             ans = ans=output["choices"][0]["text"].split("### 応答:")[1].split("###")[0]
    except:
             ans = output["choices"][0]["text"].split("### 応答:")[1]
    print("final ans",ans)
    result=200
    return {'message':result, "out":ans,"all_out":output }

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8005)

クライアント側

import requests
import json

# Infer with prompt without any additional input
data = {"sys_msg" : "英語のcentenceを翻訳する文脈が含まれています。与えられた指示に従い、英文を日本語に訳しなさい",
"user_query":"以下の英文を正しい日本語に訳しなさい。",
"user":" The image shows a residential area with tall trees on either side of the road. There are buildings on either side of the road, and a park in the distance. The sky is a light blue color with some clouds.\
The image shows a street with trees on either side of the road. There are buildings in the background with windows and balconies. The sky is blue and there are clouds in the background.\
This image is a cityscape with neon lights and tall buildings in the background. There are cars parked on the street and people walking in the foreground. The overall atmosphere is dark and moody, with red and pink tones in the neon lights..",
                "max_token":300,
                "temperature":0.0
}

# FastAPIエンドポイントのURL
url = 'http://192.168.5.104:8005/generate/'  # FastAPIサーバーのURLに合わせて変更してください

# POSTリクエストを送信
response = requests.post(url, json=data)

# レスポンスを表示
if response.status_code == 200:
    result = response.json()
    print("サーバーからの応答message:", result.get("message"))
    print("サーバーからの応答out:", result.get("out"))
    
else:
    print("リクエストが失敗しました。ステータスコード:", response.status_code)

サーバーからの応答message: 200
サーバーからの応答out: その画像は、住宅地の風景を映している。道路の両脇には高い木があり、背景には建物がある。遠くに公園がある。空は明るい青色で、雲が浮かんでいる。その画像は、道路の両脇に木がある住宅街の風景だ。背景には建物があり、その窓やバルコニーが見える。空は青く、雲が浮かんでいる。その画像は、ネオンサインや高層ビルがある都市の風景だ。道路には車が駐車しており、人々が歩いている。空は暗く、陰気で、赤やピンクの色合いがある。

翻訳結果
この例では以下の英文を翻訳させています。

The image shows a residential area with tall trees on either side of the road. There are buildings on either side of the road, and a park in the distance. The sky is a light blue color with some clouds.
The image shows a street with trees on either side of the road. There are buildings in the background with windows and balconies. The sky is blue and there are clouds in the background.
This image is a cityscape with neon lights and tall buildings in the background. There are cars parked on the street and people walking in the foreground. The overall atmosphere is dark and moody, with red and pink tones in the neon lights.

その画像は、住宅地の風景を映している。道路の両脇には高い木があり、背景には建物がある。遠くに公園がある。空は明るい青色で、雲が浮かんでいる。その画像は、道路の両脇に木がある住宅街の風景だ。背景には建物があり、その窓やバルコニーが見える。空は青く、雲が浮かんでいる。その画像は、ネオンサインや高層ビルがある都市の風景だ。道路には車が駐車しており、人々が歩いている。空は暗く、陰気で、赤やピンクの色合いがある。
temperature=0.1のとき
その画像は、住宅地の風景を映している。道の両脇には高い木があり、道の向こうには建物がある。遠くに公園が見える。空は明るい青色で、雲が浮かんでいる。その画像は、道の両脇に木がある住宅街の風景だ。背景には建物があり、窓やバルコニーが見える。空は青く、雲が浮かんでいる。その画像は、ネオンサインや高層ビルがある都市の風景だ。道には車が駐車しており、人々が歩いている。全体的な雰囲気は暗く、赤やピンクの色合いがある。
temperature=0.2以上だと省略が始まります。

google翻訳だと以下のような文章になります。

この画像には、道路の両側に高い木がある住宅地が示されています。道の両側には建物があり、遠くには公園があります。空は水色で雲もあり、道の両側に木々が生い茂る街路が描かれています。背景には窓とバルコニーのある建物があります。空は青く、背景には雲があります。ネオンや高層ビルを背景に街並みを描いた画像です。路上に車が停まっていて、前を歩いている人がいます。全体の雰囲気は、ネオンの中に赤とピンクを基調とした、ダークでムーディーな雰囲気です。

口調を変える

"user_query":"以下の英文を必ず正しい日本語に訳してください。回答は、です。ます。でお願いします。",
とすると柔らかい感じの回答です。プロンプトにかなり忠実。

この画像は、住宅地の通りを映したものです。道の両脇には高い木があり、道の向こうには建物があります。空は明るい青色で、雲が浮かんでいます。この画像は、住宅地の通りを映したものです。道の向こうには建物があり、空は青く、雲が浮かんでいます。この画像は、ネオンサインや高層ビルがある都市の風景です。道には車が駐車しており、人々が歩いています。空は暗く、陰気で、赤やピンクの色合いがあります。

メモ
自分用のメモとしてまとました。もう少しプロンプトを工夫すると口調が柔らかくなるかもしれません。