メインコンテンツへスキップ
見出し画像

最新のjapanese-stablelm-3b-4e1t-instructとjapanese-stablelm-instruct-gamma-7bを試してAPI化とキャラ付け

    japanese-stablelm-3b-4e1t-instructとjapanese-stablelm-instruct-gamma-7b及びその他のスタンダード版が本日公開されました。早速動かしましたので報告とAPI化も出来てしまったので記事にしました。

    環境

    これまでの記事と同じです。

    公式コード

    当然動きます。今回からtokenizerが変更になっています。

    import torch
    from transformers import AutoTokenizer, AutoModelForCausalLM
    
    tokenizer = AutoTokenizer.from_pretrained("stabilityai/japanese-stablelm-3b-4e1t-instruct")
    model = AutoModelForCausalLM.from_pretrained(
      "stabilityai/japanese-stablelm-3b-4e1t-instruct",
      trust_remote_code=True,
      torch_dtype="auto",
    )
    model.eval()
    
    if torch.cuda.is_available():
        model = model.to("cuda")
    
    def build_prompt(user_query, inputs="", sep="\n\n### "):
        sys_msg = "以下は、タスクを説明する指示と、文脈のある入力の組み合わせです。要求を適切に満たす応答を書きなさい。"
        p = sys_msg
        roles = ["指示", "応答"]
        msgs = [": \n" + user_query, ": \n"]
        if inputs:
            roles.insert(1, "入力")
            msgs.insert(1, ": \n" + inputs)
        for role, msg in zip(roles, msgs):
            p += sep + role + msg
        return p
    
    # Infer with prompt without any additional input
    user_inputs = {
        "user_query": "与えられたことわざの意味を小学生でも分かるように教えてください。",
        "inputs": "情けは人のためならず"
    }
    prompt = build_prompt(**user_inputs)
    
    input_ids = tokenizer.encode(
        prompt, 
        add_special_tokens=False, 
        return_tensors="pt"
    )
    
    tokens = model.generate(
        input_ids.to(device=model.device),
        max_new_tokens=256,
        temperature=1,
        top_p=0.95,
        do_sample=True,
    )
    
    out = tokenizer.decode(tokens[0][input_ids.shape[1]:], skip_special_tokens=True).strip()
    print(out)

    7Bモデルに変更するには、tokenizer部分を書き換えます。

    tokenizer = AutoTokenizer.from_pretrained("stabilityai/japanese-stablelm-instruct-gamma-7b")
    model = AutoModelForCausalLM.from_pretrained(
      "stabilityai/japanese-stablelm-instruct-gamma-7b",
      torch_dtype="auto",
    )

    APIサーバ化とキャラ設定

    これ、実は簡単で、この記事の前の記事のモデルを変えるだけです。プロンプトの構成が同じなので、tokenizerとmodelを変更すればすぐに動きました。違いは以下の部分のみです。このコードはstabilityai/japanese-stablelm-3b-4e1t-instructのときの例です。

    tokenizer = AutoTokenizer.from_pretrained("stabilityai/japanese-stablelm-3b-4e1t-instruct")
    
    model = AutoModelForCausalLM.from_pretrained(
      "stabilityai/japanese-stablelm-3b-4e1t-instruct",
        trust_remote_code=True,
      torch_dtype="auto",
    )

    サーバの全コード

    import torch
    from transformers import AutoTokenizer, AutoModelForCausalLM
    from fastapi import FastAPI,Form
    from fastapi.responses import HTMLResponse
    from pydantic import BaseModel
    
    tokenizer = AutoTokenizer.from_pretrained("stabilityai/japanese-stablelm-3b-4e1t-instruct")
    
    model = AutoModelForCausalLM.from_pretrained(
      "stabilityai/japanese-stablelm-3b-4e1t-instruct",
        trust_remote_code=True,
      torch_dtype="auto",
    )
    model.eval()
    if torch.cuda.is_available():
        model = model.to("cuda")
    
    model.eval()
    
    app = FastAPI()
    
    # rootエンドポイント
    @app.get("/", response_class=HTMLResponse)
    async def get_root(request):
        return templates.TemplateResponse("index.html", {"request": request})
    
    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
    
        user_inputs = {
                                   "user_query": user_query,
                                   "inputs": user,
                                       }
        prompt = build_prompt(sys_msg ,**user_inputs)
        print("prompt =",prompt )
        input_ids = tokenizer.encode(
                                    prompt, 
                                    add_special_tokens=False, 
                                    return_tensors="pt"
                                    )
        
        # パッドトークンIDの設定
        pad_token_id = tokenizer.eos_token_id  # パディングトークンIDをeos_token_idに設定
    
        tokens = model.generate(
                                    input_ids.to(device=model.device),
                                    max_new_tokens=max_token,
                                    temperature=get_temperature,
                                    top_p=0.95,
                                    do_sample=True,
                                    pad_token_id= pad_token_id,
                                    )
        all_out = tokenizer.decode(tokens[0][input_ids.shape[1]:], skip_special_tokens=True).strip()
        print("SYS_OUT=", all_out)
        out=all_out.split("###")[0]
        result=200
        return {'message':result, "out":out,"all_out":all_out}
    
    def build_prompt(sys_msg ,user_query, inputs="", sep="\n\n### "):
        p = sys_msg
        roles = ["指示", "応答"]
        msgs = [": \n" + user_query, ": \n"]
        if inputs:
            roles.insert(1, "入力")
            msgs.insert(1, ": \n" + inputs)
        for role, msg in zip(roles, msgs):
            p += sep + role + msg
        return p
    
    if __name__ == "__main__":
        import uvicorn
        uvicorn.run(app, host="0.0.0.0", port=8005)

    gradio−GUIによるキャラ作り

    こちらも以下の記事でtokenizerとmodelを変更すればすぐに動きました。ソースコードは省略します。APIサーバと同様にtokenizerとmodel部分を変更してください。

    これまでの様子

    japanese-stablelm-3b-4e1t-instructがstabilityai/japanese-stablelm-instruct-alpha-7b-v2と同程度かなという感想です。ただ、質問に関係の無い回とをするケースは多いようです。プロンプトの工夫が必要なんでしょうね。

    stabilityai/japanese-stablelm-instruct-alpha-7b-v2でGUI化のプロンプトテス環境やAPIサーバ化をやっていたので最新のモデルの評価がいち早く出来ました。ちょっとラッキーですね。


     
     
    AItuberめぐとそのお友達や、関連するAI技術の記事を中心に書いています。

    あなたへのおすすめ