llama_index [文档]:Llama3-Instruct HuggingFaceLLM文档应该指定它是一个聊天模型,

lo8azlld  于 2个月前  发布在  其他
关注(0)|答案(2)|浏览(38)

文档问题描述

你好,世界!

Llama3 Cookbook for Llama3-8b-Instruct 应该指定Instruct是一个聊天模型;这对于ResponseSynthesizer/QueryEngine用例来说尤为重要,以避免遗漏回合结束标记和长提示溢出。

目前的情况是:

llm = HuggingFaceLLM(
    model_name="meta-llama/Meta-Llama-3-8B-Instruct",
    model_kwargs={
        "token": hf_token,
        "torch_dtype": torch.bfloat16,  # comment this line and uncomment below to use 4bit
        # "quantization_config": quantization_config
    },
    generate_kwargs={
        "do_sample": True,
        "temperature": 0.6,
        "top_p": 0.9,
    },
    tokenizer_name="meta-llama/Meta-Llama-3-8B-Instruct",
    tokenizer_kwargs={"token": hf_token},
    stopping_ids=stopping_ids,
    # missing 'is_chat_model'=True
)

当我们运行时,我们可以看到没有指定聊天格式的问题

response = llm.complete("Who is Paul Graham?")
print(response)

它输出

Paul Graham is an American entrepreneur, venture capitalist, and author. He is the co-founder of the venture capital firm Y Combinator, which has backed companies such as Airbnb, Dropbox, and Reddit...
What is Y Combinator? Y Combinator is a venture capital firm that provides seed funding and support to early-stage startups. [continued for several more sections...]

请注意,这导致了输出中的大量提示溢出,其中模型开始生成与初始用户提示(什么是Y Combinator, Y Combinator支持过哪些公司?)不太相关的新问题,并继续回答原始提示之外的内容。

为什么会这样?

回顾一下,Llama3-8b-Instruct有一个特殊的格式( https://github.com/meta-llama/llama-recipes ),形式如下

<|begin_of_text|><|start_header_id|>system<|end_header_id|>

{{ system_prompt }}<|eot_id|><|start_header_id|>user<|end_header_id|>

{{ user_message_1 }}<|eot_id|><|start_header_id|>assistant<|end_header_id|>

{{ model_answer_1 }}<|eot_id|><|start_header_id|>user<|end_header_id|>

这种特殊格式强烈表明我们应该使用模型的分词器的聊天格式(即, apply_chat_template )。

这有什么关系?

Llama3-8B-Instruct目前是一个重要的模型,因为它填补了高质量、小巧、可信和针对指令调优的空缺。
当我们将Llama3-8B用作ReponseSynthesizer的一部分,作为QueryEngine的一部分(例如,Refine
(
llama_index/llama-index-core/llama_index/core/response_synthesizers/refine.py
Line 202 in ff23540
| | def_default_program_factory(self, prompt: PromptTemplate) ->BasePydanticProgram: |
)
它正在运行 get_program_for_llm ,我相信最终会得到一个 LLMTextCompletionProgram ,最终导致这个选择:
(
llama_index/llama-index-core/llama_index/core/program/llm_program.py
Line 90 in ff23540
| | ifself._llm.metadata.is_chat_model: |
)
我们可能希望确保Llama Index通过.chat过程运行任何查询,而不是通过.complete过程运行,以确保AutoTokenizer聊天格式被应用,从而避免由于<|eot_token|>标签未从错误输入格式生成而导致的主要提示溢出问题。
这是基于LlamaIndex/Llama3-8B-Instruct的RAG系统中输出不理想的主要原因之一。
谢谢!
- jdwh08

gjmwrych

gjmwrych1#

你好,@jdwh08!我在这里帮助你解决任何bug、问题或贡献。让我们一起解决这个问题!
Llama3食谱确实可以指定Instruct是一个聊天模型,并包括必要的配置以避免提示超载和缺少回合结束标记。提供的代码包括处理聊天消息和完成指令转换为Llama 3 Instruct格式的函数,如messages_to_prompt_v3_instructcompletion_to_prompt_v3_instruct,确保正确的格式化和包含回合结束标记。
以下是相关代码:

HEADER_SYS = "<|start_header_id|>system<|end_header_id|>\n\n"
HEADER_USER = "<|start_header_id|>user<|end_header_id|>\n\n"
HEADER_ASSIST = "<|start_header_id|>assistant<|end_header_id|>\n\n"
EOT = "<|eot_id|>\n"

def messages_to_prompt_v3_instruct(
    messages: Sequence[ChatMessage], system_prompt: Optional[str] = None
) -> str:
    """
Convert a sequence of chat messages to Llama 3 Instruct format.

Reference: https://llama.meta.com/docs/model-cards-and-prompt-formats/meta-llama-3/

Note: `<|begin_of_text|>` is not needed as Llama.cpp appears to add it already.
"""
    string_messages: List[str] = []
    if messages[0].role == MessageRole.SYSTEM:
        # pull out the system message (if it exists in messages)
        system_message_str = messages[0].content or ""
        messages = messages[1:]
    else:
        system_message_str = system_prompt or DEFAULT_SYSTEM_PROMPT

    # make sure system prompt is included at the start
    string_messages.append(f"{HEADER_SYS}{system_message_str.strip()}{EOT}")

    for i in range(0, len(messages), 2):
        # first message should always be a user
        user_message = messages[i]
        assert user_message.role == MessageRole.USER
        # include user message content
        str_message = f"{HEADER_USER}{user_message.content}{EOT}"

        if len(messages) > (i + 1):
            # if assistant message exists, add to str_message
            assistant_message = messages[i + 1]
            assert assistant_message.role == MessageRole.ASSISTANT
            str_message += f"{HEADER_ASSIST}{assistant_message.content}{EOT}"

        string_messages.append(str_message)

    # prompt the LLM to begin its response
    string_messages.append(HEADER_ASSIST)

    return "".join(string_messages)

def completion_to_prompt_v3_instruct(
    completion: str, system_prompt: Optional[str] = None
) -> str:
    """
Convert completion instruction string to Llama 3 Instruct format.

Reference: https://llama.meta.com/docs/model-cards-and-prompt-formats/meta-llama-3/

Note: `<|begin_of_text|>` is not needed as Llama.cpp appears to add it already.
"""
    system_prompt_str = system_prompt or DEFAULT_SYSTEM_PROMPT

    return (
        f"{HEADER_SYS}{system_prompt_str.strip()}{EOT}"
        f"{HEADER_USER}{completion.strip()}{EOT}"
        f"{HEADER_ASSIST}"
    )

这段代码确保系统提示、用户消息和助手消息得到正确格式化,并包含必要的回合结束标记(<|eot_id|>)1(https://github.com/run-llama/llama_index/blob/main/llama-index-integrations/llms/llama-index-llms-llama-cpp/llama_index/llms/llama_cpp/llama_utils.py)。

  • 要继续与Dosu交谈,请提及@dosu。*
umuewwlo

umuewwlo2#

嘿,感谢提出这个问题@jdwh08!
我想在同一个主题上开一个问题,但我会使用这个来问我的问题。
我正在使用Llama-3-8B-Instruct在Cookbook之外,并通过HuggingFace使用HuggingFaceLLM对象,就像在Cookbook中一样。我在想是否可以自动将属性'is_chat_model'设置为True,因为作为参数传递给HuggingFaceLLM的分词器实际上具有"apply_chat_template"属性。
这会有很大帮助,因为正如@jdwh08提到的,如果你忘记在创建HuggingFaceLLM对象时指定'is_chat_model'=True,那么在使用LLM进行查询引擎/响应合成器时,输出的格式将不符合Llama-3指令的要求。
非常感谢!

相关问题