Files
wehub-resource-sync 770d92cb1f
Lint / lint (push) Waiting to run
Windows CI / Windows (push) Waiting to run
Build Docs / Deploy Docs (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:23:58 +08:00

258 lines
8.2 KiB
C++

/*!
* Copyright (c) 2023-2025 by Contributors
* \file serve/data.h
*/
#ifndef MLC_LLM_SERVE_DATA_H_
#define MLC_LLM_SERVE_DATA_H_
#include <tvm/ffi/container/array.h>
#include <tvm/ffi/container/shape.h>
#include <tvm/ffi/object.h>
#include <tvm/ffi/optional.h>
#include <tvm/ffi/reflection/registry.h>
#include <tvm/ffi/string.h>
#include <tvm/runtime/tensor.h>
#include <atomic>
#include <optional>
#include "../tokenizers/tokenizers.h"
namespace mlc {
namespace llm {
namespace serve {
using namespace tvm::runtime;
using tvm::ffi::Object;
using tvm::ffi::ObjectPtr;
using tvm::ffi::ObjectRef;
using tvm::ffi::Optional;
using tvm::ffi::Shape;
class Model;
/****************** DataNode ******************/
/*! \brief The base class of multi-modality data (text, tokens, embedding, etc). */
class DataNode : public Object {
public:
/*! \brief Get the length (equivalent number of tokens) of the data. */
virtual int GetLength() const = 0;
/*!
* \brief Compute the embedding of this data with regard to the input model.
* When the input destination pointer is not nullptr, it in-place writes the
* embedding into the input destination array at the given offset.
* Otherwise, the embeddings will be directly returned back.
* \param model The model to take embeddings from.
* \param dst The destination array of the embedding lookup.
* \param offset The token offset where the computed embeddings will be written
* into the destination array.
* \return The updated destination embedding array or the computed embeddings.
* \note When `dst` is nullptr, we require `offset` to be 0.
*/
virtual ObjectRef GetEmbedding(Model model, ObjectRef* dst = nullptr, int offset = 0) const = 0;
static void RegisterReflection() {
namespace refl = tvm::ffi::reflection;
refl::ObjectDef<DataNode>();
}
static constexpr const bool _type_has_method_sequal_reduce = false;
static constexpr const bool _type_has_method_shash_reduce = false;
static constexpr const uint32_t _type_child_slots = 3;
TVM_FFI_DECLARE_OBJECT_INFO("mlc.serve.Data", DataNode, Object);
};
class Data : public ObjectRef {
public:
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(Data, ObjectRef, DataNode);
};
/*! \brief Split the given data array into two arrays at the "split_pos" position. */
std::pair<Array<Data>, Array<Data>> SplitData(const Array<Data>& original_data, int total_length,
int split_pos);
/****************** TextDataNode ******************/
/*! \brief The class of text data, containing a text string. */
class TextDataNode : public DataNode {
public:
/*! \brief The text string. */
tvm::ffi::String text;
int GetLength() const final;
ObjectRef GetEmbedding(Model model, ObjectRef* dst = nullptr, int offset = 0) const final;
static void RegisterReflection() {
namespace refl = tvm::ffi::reflection;
refl::ObjectDef<TextDataNode>();
}
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("mlc.serve.TextData", TextDataNode, DataNode);
};
class TextData : public Data {
public:
explicit TextData(String text);
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(TextData, Data, TextDataNode);
};
/****************** TokenDataNode ******************/
/*! \brief The class of token data, containing a list of token ids. */
class TokenDataNode : public DataNode {
public:
/*! \brief The token ids. */
Shape token_ids;
int GetLength() const final;
ObjectRef GetEmbedding(Model model, ObjectRef* dst = nullptr, int offset = 0) const final;
static void RegisterReflection() {
namespace refl = tvm::ffi::reflection;
refl::ObjectDef<TokenDataNode>();
}
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("mlc.serve.TokenData", TokenDataNode, DataNode);
};
class TokenData : public Data {
public:
explicit TokenData(Shape token_ids);
explicit TokenData(std::vector<int32_t> token_ids);
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(TokenData, Data, TokenDataNode);
};
/****************** ImageDataNode ******************/
/*! \brief The class of image data, containing a 3D array of pixel values. */
class ImageDataNode : public DataNode {
public:
/*! \brief The pixel values. */
Tensor image;
int embed_size;
int GetLength() const final;
ObjectRef GetEmbedding(Model model, ObjectRef* dst = nullptr, int offset = 0) const final;
static void RegisterReflection() {
namespace refl = tvm::ffi::reflection;
refl::ObjectDef<ImageDataNode>();
}
TVM_FFI_DECLARE_OBJECT_INFO_FINAL("mlc.serve.ImageData", ImageDataNode, DataNode);
};
class ImageData : public Data {
public:
explicit ImageData(Tensor image, int embed_size);
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(ImageData, Data, ImageDataNode);
};
/****************** SampleResult ******************/
// The pair of a token id and its probability in sampling.
using TokenProbPair = std::pair<int32_t, float>;
/*!
* \brief The class of sampler's sampling result.
* It's not a TVM object since it will not be used directly on Python side.
*/
struct SampleResult {
/*! \brief The token id and probability of the sampled token. */
TokenProbPair sampled_token_id;
/*! \brief The token id and probability of the tokens with top probabilities. */
std::vector<TokenProbPair> top_prob_tokens;
/*! \brief Get the sampled token id. */
int32_t GetTokenId() const;
/*!
* \brief Get the logprob JSON string of this token with regard
* to OpenAI API at https://platform.openai.com/docs/api-reference/chat/object.
* \param tokenizer The tokenizer for token table lookup.
* \param logprob A boolean indicating if need to return log probability.
* \return A JSON string that conforms to the logprob spec in OpenAI API.
*/
std::string GetLogProbJSON(const Tokenizer& tokenizer, bool logprob) const;
};
/****************** RequestStreamOutput ******************/
/*!
* \brief The generated delta request output that is streamed back
* through callback stream function.
*
* \note: This output object corresponds to parallel generated outputs when n != 1.
*
* For example, if n=2, then group_delta_token_ids[0] matches to the output stream 0
* and group_delta_token_ids[1] matches to the output stream 1
*/
class RequestStreamOutputObj : public Object {
public:
/*! \brief The id of the request that the function is invoked for. */
String request_id;
/*!
* \brief The new generated token ids since the last callback invocation
* for the input request.
*/
std::vector<std::vector<int64_t>> group_delta_token_ids;
/*! \brief The logprobs JSON strings of the new generated tokens since last invocation. */
std::optional<std::vector<std::vector<String>>> group_delta_logprob_json_strs;
/*!
* \brief The finish reason of the request when it is finished,
* of None if the request has not finished yet.
*/
std::vector<Optional<String>> group_finish_reason;
/*!
* \brief The usage field of the response, this is global to all streams.
*/
Optional<String> request_final_usage_json_str;
/*!
* \brief The extra prefix string of all requests.
*/
std::vector<String> group_extra_prefix_string;
std::atomic<bool> unpacked = false;
static void RegisterReflection() {
namespace refl = tvm::ffi::reflection;
refl::ObjectDef<RequestStreamOutputObj>();
}
static constexpr const bool _type_has_method_sequal_reduce = false;
static constexpr const bool _type_has_method_shash_reduce = false;
static constexpr const bool _type_mutable = true;
TVM_FFI_DECLARE_OBJECT_INFO("mlc.serve.RequestStreamOutput", RequestStreamOutputObj, Object);
};
/*!
* \brief Managed reference to RequestStreamOutputObj.
* \sa RequestStreamOutputObj
*/
class RequestStreamOutput : public ObjectRef {
public:
explicit RequestStreamOutput(
String request_id, std::vector<std::vector<int64_t>> group_delta_token_ids,
std::optional<std::vector<std::vector<String>>> group_delta_logprob_json_strs,
std::vector<Optional<String>> group_finish_reason,
std::vector<String> group_extra_prefix_string);
static RequestStreamOutput Usage(String request_id, String request_final_usage_json_str);
TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(RequestStreamOutput, ObjectRef,
RequestStreamOutputObj);
};
} // namespace serve
} // namespace llm
} // namespace mlc
#endif // MLC_LLM_SERVE_DATA_H_