Open YunchaoYang opened 4 months ago
The following is from
整个推理过程大大致流程如下图所示,即 1 给定一定数量的 prompts(字符串数组)
如上图我们可以看到 vLLM 为输入的句子设计了很多子模块,这些模块的用处各不相同,但是有彼此之间有关系,下面分别详细介绍一下。
首先看到 SequenceStatus,其源代码如下:
class SequenceStatus(enum.Enum):
"""Status of a sequence."""
WAITING = enum.auto() # 等待中,句子还没开始推理,或者推理还未结束
RUNNING = enum.auto() # 运行中
SWAPPED = enum.auto() # 已交换
FINISHED_STOPPED = enum.auto() # 已停止
FINISHED_LENGTH_CAPPED = enum.auto() # 已长度限制
FINISHED_ABORTED = enum.auto() # 已中止
FINISHED_IGNORED = enum.auto() # 已忽略
@staticmethod
def is_finished(status: "SequenceStatus") -> bool:
# 判断状态是否为已停止、已长度限制、已中止或已忽略
return status in [
SequenceStatus.FINISHED_STOPPED,
SequenceStatus.FINISHED_LENGTH_CAPPED,
SequenceStatus.FINISHED_ABORTED,
SequenceStatus.FINISHED_IGNORED,
]
SequenceData 用于存储与序列相关的数据。这个类有三个属性:prompt_token_ids(提示词的标记ID)、output_token_ids(生成文本的标记ID)和cumulative_logprob(累计对数概率)。
class SequenceData:
def __init__(
self,
prompt_token_ids: List[int],
) -> None:
self.prompt_token_ids = prompt_token_ids
self.output_token_ids: List[int] = []
self.cumulative_logprob = 0.0
Sequence 用于存储序列的数据、状态和块信息,且每个序列有唯一标识,即seq_id。注意看下面的代码:
数据其实是通过上面的 SequenceData 保存的 默认初始化状态,所有句子序列的状态都是 SequenceStatus.WAITING 所谓块信息,其实就是 vLLM 会在初始化阶段预留出一定数量的CPU 和 GPU 内存,一般是以 token 为单位的,例如在初始化的时候会使用值全为 0,大小为 (256, 128)的 prompt_ids做 warm up。每个序列会按照实际大小申请 block 来记录内存使用情况,即序列 token 数越多,属性logical_token_blocks包含的 block 个数也就越多。
class Sequence:
def __init__(
self,
seq_id: int,
prompt: str,
prompt_token_ids: List[int],
block_size: int,
) -> None:
self.seq_id = seq_id
self.prompt = prompt
self.block_size = block_size
self.data = SequenceData(prompt_token_ids) # 数据
self.logical_token_blocks: List[LogicalTokenBlock] = []
# Initialize the logical token blocks with the prompt token ids.
self._append_tokens_to_blocks(prompt_token_ids) # 块信息
self.status = SequenceStatus.WAITING # 状态
...
Sequence只是单个序列的表示方式,seq_id是它的唯一标识。SequenceGroup则是为了表示多个序列,request_id是它的唯一标识,表示是第几个请求。
具体而言,可以看到init函数有个参数是 seqs: List[Sequence],它表示由一个或多个 Sequence 组成的列表,然后会通过self.seqs_dict = {seq.seq_id: seq for seq in seqs}转化成字典方便管理,这个字典的 key 是每个 Sequence 的唯一标识seq_id。
class SequenceGroup:
def __init__(
self,
request_id: str,
seqs: List[Sequence],
sampling_params: SamplingParams,
arrival_time: float,
lora_request: Optional[LoRARequest] = None,
prefix: Optional[Prefix] = None,
) -> None:
self.request_id = request_id
self.seqs_dict = {seq.seq_id: seq for seq in seqs}
self.sampling_params = sampling_params
self.arrival_time = arrival_time
...
SamplingParams 包含以下参数:
n:要生成的序列的数量,默认为 1。 best_of:从多少个序列中选择最佳序列,需要大于 n,默认等于 n。 temperature:用于控制生成结果的随机性,较低的温度会使生成结果更确定性,较高的温度会使生成结果更随机。 top_p:用于过滤掉生成词汇表中概率低于给定阈值的词汇,控制随机性。 top_k:选择前 k 个候选 token,控制多样性。 presence_penalty:用于控制生成结果中特定词汇的出现频率。 frequency_penalty:用于控制生成结果中词汇的频率分布。 repetition_penalty:用于控制生成结果中的词汇重复程度。 use_beam_search:是否使用束搜索来生成序列。 length_penalty:用于控制生成结果的长度分布。 early_stopping:是否在生成过程中提前停止。 stop:要停止生成的词汇列表。 stop_token_ids:要停止生成的词汇的ID列表。 include_stop_str_in_output:是否在输出结果中包含停止字符串。 ignore_eos:在生成过程中是否忽略结束符号。 max_tokens:生成序列的最大长度。 logprobs:用于记录生成过程的概率信息。 prompt_logprobs:用于记录生成过程的概率信息,用于特定提示。 skip_special_tokens:是否跳过特殊符号。 spaces_between_special_tokens:是否在特殊符号之间添加空格。 这些参数的设置通常取决于具体需求和模型性能。以下是一些常见的设置指导方法:
temperature:较低的温度(如0.2)会产生更确定性的结果,而较高的温度(如0.8)会产生更随机的结果。您可以根据您的需求进行调整。 presence_penalty、frequency_penalty 和 repetition_penalty:这些参数可以用于控制生成结果中的词汇分布和重复程度。您可以根据您的需求进行调整。 use_beam_search:束搜索通常用于生成更高质量的结果,但可能会降低生成速度。您可以根据您的需求进行调整。 length_penalty:这个参数可以用于控制生成结果的长度。较高的值会产生更长的结果,而较低的值会产生更短的结果。您可以根据您的需求进行调整。 early_stopping:如果您不希望生成过长的结果,可以设置此参数为True。 stop 和 stop_token_ids:您可以使用这些参数来指定生成结果的结束条件。
HuggingFace Transformers
Llama.cpp
Llamafile
Deepspeed
Huggingface TGI
1. Ollama
1. use Ollama CLI:
A list of available base models: https://github.com/ollama/ollama#model-library
2. use Modelfile to customize your model.
The format is similar to DockerFile. For example:
More examples are available in the examples directory.
Ollama + Langchain for local serving RAG model:
Following this tutorial to build a local serving LLM with RAG for document retrieval:
pip install langchain pip install pypdf pip install chromadb pip install gradio pip install fastembed pip install
build a chatbox with gradio and ollama: https://bibek-poudel.medium.com/create-your-own-chatbot-with-llama2-ollama-and-gradio-5c60ecb1aad0