Image-Text-to-Text
Transformers
Safetensors
mage_vl
multimodal
vision-language-model
mage-vl
video-understanding
streaming
conversational
custom_code
Instructions to use microsoft/Mage-VL with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use microsoft/Mage-VL with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="microsoft/Mage-VL", trust_remote_code=True) messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# Load model directly from transformers import AutoModelForImageTextToText model = AutoModelForImageTextToText.from_pretrained("microsoft/Mage-VL", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use microsoft/Mage-VL with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "microsoft/Mage-VL" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "microsoft/Mage-VL", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/microsoft/Mage-VL
- SGLang
How to use microsoft/Mage-VL with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "microsoft/Mage-VL" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "microsoft/Mage-VL", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "microsoft/Mage-VL" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "microsoft/Mage-VL", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use microsoft/Mage-VL with Docker Model Runner:
docker model run hf.co/microsoft/Mage-VL
| // Copyright (c) Microsoft Corporation. | |
| // Licensed under the MIT License. | |
| namespace py = pybind11; | |
| RansEncoder::RansEncoder() | |
| { | |
| m_encoder0 = std::make_shared<RansEncoderLibMultiThread>(); | |
| m_encoder1 = std::make_shared<RansEncoderLibMultiThread>(); | |
| } | |
| void RansEncoder::encode_y(const py::array_t<int16_t>& symbols, const int cdf_group_index) | |
| { | |
| py::buffer_info symbols_buf = symbols.request(); | |
| int16_t* symbols_ptr = static_cast<int16_t*>(symbols_buf.ptr); | |
| int symbolSize = static_cast<int>(symbols.size()); | |
| if (m_use_two_encoders) { | |
| int symbolSize0 = symbolSize / 2; | |
| int symbolSize1 = symbolSize - symbolSize0; | |
| auto vec_symbols0 = std::make_shared<std::vector<int16_t>>(symbolSize0); | |
| memcpy(vec_symbols0->data(), symbols_ptr, symbolSize0 * sizeof(int16_t)); | |
| m_encoder0->encode_y(vec_symbols0, cdf_group_index); | |
| auto vec_symbols1 = std::make_shared<std::vector<int16_t>>(symbolSize1); | |
| memcpy(vec_symbols1->data(), symbols_ptr + symbolSize0, symbolSize1 * sizeof(int16_t)); | |
| m_encoder1->encode_y(vec_symbols1, cdf_group_index); | |
| } else { | |
| auto vec_symbols0 = std::make_shared<std::vector<int16_t>>(symbolSize); | |
| memcpy(vec_symbols0->data(), symbols_ptr, symbolSize * sizeof(int16_t)); | |
| m_encoder0->encode_y(vec_symbols0, cdf_group_index); | |
| } | |
| } | |
| void RansEncoder::encode_z(const py::array_t<int8_t>& symbols, const int cdf_group_index, | |
| const int start_offset, const int per_channel_size) | |
| { | |
| py::buffer_info symbols_buf = symbols.request(); | |
| int8_t* symbols_ptr = static_cast<int8_t*>(symbols_buf.ptr); | |
| int symbolSize = static_cast<int>(symbols.size()); | |
| if (m_use_two_encoders) { | |
| int symbolSize0 = symbolSize / 2; | |
| int symbolSize1 = symbolSize - symbolSize0; | |
| int channel_half = symbolSize0 / per_channel_size; | |
| auto vec_symbols0 = std::make_shared<std::vector<int8_t>>(symbolSize0); | |
| memcpy(vec_symbols0->data(), symbols_ptr, symbolSize0 * sizeof(int8_t)); | |
| m_encoder0->encode_z(vec_symbols0, cdf_group_index, start_offset, per_channel_size); | |
| auto vec_symbols1 = std::make_shared<std::vector<int8_t>>(symbolSize1); | |
| memcpy(vec_symbols1->data(), symbols_ptr + symbolSize0, symbolSize1 * sizeof(int8_t)); | |
| m_encoder1->encode_z(vec_symbols1, cdf_group_index, start_offset + channel_half, | |
| per_channel_size); | |
| } else { | |
| auto vec_symbols0 = std::make_shared<std::vector<int8_t>>(symbolSize); | |
| memcpy(vec_symbols0->data(), symbols_ptr, symbolSize * sizeof(int8_t)); | |
| m_encoder0->encode_z(vec_symbols0, cdf_group_index, start_offset, per_channel_size); | |
| } | |
| } | |
| int RansEncoder::add_cdf(const py::array_t<int32_t>& cdfs, const py::array_t<int32_t>& cdfs_sizes, | |
| const py::array_t<int32_t>& offsets) | |
| { | |
| py::buffer_info cdfs_sizes_buf = cdfs_sizes.request(); | |
| py::buffer_info offsets_buf = offsets.request(); | |
| int32_t* cdfs_sizes_ptr = static_cast<int32_t*>(cdfs_sizes_buf.ptr); | |
| int32_t* offsets_ptr = static_cast<int32_t*>(offsets_buf.ptr); | |
| int cdf_num = static_cast<int>(cdfs_sizes.size()); | |
| auto vec_cdfs_sizes = std::make_shared<std::vector<int32_t>>(cdf_num); | |
| memcpy(vec_cdfs_sizes->data(), cdfs_sizes_ptr, sizeof(int32_t) * cdf_num); | |
| auto vec_offsets = std::make_shared<std::vector<int32_t>>(offsets.size()); | |
| memcpy(vec_offsets->data(), offsets_ptr, sizeof(int32_t) * offsets.size()); | |
| int per_vector_size = static_cast<int>(cdfs.size() / cdf_num); | |
| auto vec_cdfs = std::make_shared<std::vector<std::vector<int32_t>>>(cdf_num); | |
| auto cdfs_raw = cdfs.unchecked<2>(); | |
| for (int i = 0; i < cdf_num; i++) { | |
| std::vector<int32_t> t(per_vector_size); | |
| memcpy(t.data(), cdfs_raw.data(i, 0), sizeof(int32_t) * per_vector_size); | |
| vec_cdfs->at(i) = t; | |
| } | |
| int cdf_idx = m_encoder0->add_cdf(vec_cdfs, vec_cdfs_sizes, vec_offsets); | |
| m_encoder1->add_cdf(vec_cdfs, vec_cdfs_sizes, vec_offsets); | |
| return cdf_idx; | |
| } | |
| void RansEncoder::empty_cdf_buffer() | |
| { | |
| m_encoder0->empty_cdf_buffer(); | |
| m_encoder1->empty_cdf_buffer(); | |
| } | |
| void RansEncoder::flush() | |
| { | |
| m_encoder0->flush(); | |
| m_encoder1->flush(); | |
| } | |
| py::array_t<uint8_t> RansEncoder::get_encoded_stream() | |
| { | |
| if (m_use_two_encoders) { | |
| auto result0 = m_encoder0->get_encoded_stream(); | |
| int nbytes0 = static_cast<int>(result0->size()); | |
| auto result1 = m_encoder1->get_encoded_stream(); | |
| int nbytes1 = static_cast<int>(result1->size()); | |
| int identical_bytes = 0; | |
| int check_bytes = std::min(nbytes0, nbytes1); | |
| check_bytes = std::min(check_bytes, 8); | |
| for (int i = 0; i < check_bytes; i++) { | |
| if (result0->at(nbytes0 - 1 - i) != 0) { | |
| break; | |
| } | |
| if (result1->at(nbytes1 - 1 - i) != 0) { | |
| break; | |
| } | |
| identical_bytes++; | |
| } | |
| if (identical_bytes == 0 && result0->at(nbytes0 - 1) == result1->at(nbytes1 - 1)) { | |
| identical_bytes = 1; | |
| } | |
| py::array_t<uint8_t> stream(nbytes0 + nbytes1 - identical_bytes); | |
| py::buffer_info stream_buf = stream.request(); | |
| uint8_t* stream_ptr = static_cast<uint8_t*>(stream_buf.ptr); | |
| std::copy(result0->begin(), result0->end(), stream_ptr); | |
| std::reverse_copy(result1->begin(), result1->end() - identical_bytes, stream_ptr + nbytes0); | |
| return stream; | |
| } | |
| auto result0 = m_encoder0->get_encoded_stream(); | |
| int nbytes0 = static_cast<int>(result0->size()); | |
| py::array_t<uint8_t> stream(nbytes0); | |
| py::buffer_info stream_buf = stream.request(); | |
| uint8_t* stream_ptr = static_cast<uint8_t*>(stream_buf.ptr); | |
| std::copy(result0->begin(), result0->end(), stream_ptr); | |
| return stream; | |
| } | |
| void RansEncoder::reset() | |
| { | |
| m_encoder0->reset(); | |
| m_encoder1->reset(); | |
| } | |
| void RansEncoder::set_use_two_encoders(bool b) | |
| { | |
| m_use_two_encoders = b; | |
| } | |
| bool RansEncoder::get_use_two_encoders() | |
| { | |
| return m_use_two_encoders; | |
| } | |
| RansDecoder::RansDecoder() | |
| { | |
| m_decoder0 = std::make_shared<RansDecoderLibMultiThread>(); | |
| m_decoder1 = std::make_shared<RansDecoderLibMultiThread>(); | |
| } | |
| void RansDecoder::set_stream(const py::array_t<uint8_t>& encoded) | |
| { | |
| py::buffer_info encoded_buf = encoded.request(); | |
| const uint8_t* encoded_ptr = static_cast<uint8_t*>(encoded_buf.ptr); | |
| const int encoded_size = static_cast<int>(encoded.size()); | |
| auto stream0 = std::make_shared<std::vector<uint8_t>>(encoded.size()); | |
| std::copy(encoded_ptr, encoded_ptr + encoded_size, stream0->data()); | |
| m_decoder0->set_stream(stream0); | |
| if (m_use_two_decoders) { | |
| auto stream1 = std::make_shared<std::vector<uint8_t>>(encoded.size()); | |
| std::reverse_copy(encoded_ptr, encoded_ptr + encoded_size, stream1->data()); | |
| m_decoder1->set_stream(stream1); | |
| } | |
| } | |
| void RansDecoder::decode_y(const py::array_t<uint8_t>& indexes, const int cdf_group_index) | |
| { | |
| py::buffer_info indexes_buf = indexes.request(); | |
| uint8_t* indexes_ptr = static_cast<uint8_t*>(indexes_buf.ptr); | |
| int indexSize = static_cast<int>(indexes.size()); | |
| if (m_use_two_decoders) { | |
| int indexSize0 = indexSize / 2; | |
| int indexSize1 = indexSize - indexSize0; | |
| auto vec_indexes0 = std::make_shared<std::vector<uint8_t>>(indexSize0); | |
| std::copy(indexes_ptr, indexes_ptr + indexSize0, vec_indexes0->data()); | |
| m_decoder0->decode_y(vec_indexes0, cdf_group_index); | |
| auto vec_indexes1 = std::make_shared<std::vector<uint8_t>>(indexSize1); | |
| std::copy(indexes_ptr + indexSize0, indexes_ptr + indexSize, vec_indexes1->data()); | |
| m_decoder1->decode_y(vec_indexes1, cdf_group_index); | |
| } else { | |
| auto vec_indexes0 = std::make_shared<std::vector<uint8_t>>(indexSize); | |
| std::copy(indexes_ptr, indexes_ptr + indexSize, vec_indexes0->data()); | |
| m_decoder0->decode_y(vec_indexes0, cdf_group_index); | |
| } | |
| } | |
| py::array_t<int8_t> RansDecoder::decode_and_get_y(const py::array_t<uint8_t>& indexes, | |
| const int cdf_group_index) | |
| { | |
| decode_y(indexes, cdf_group_index); | |
| return get_decoded_tensor(); | |
| } | |
| void RansDecoder::decode_z(const int total_size, const int cdf_group_index, const int start_offset, | |
| const int per_channel_size) | |
| { | |
| if (m_use_two_decoders) { | |
| int symbolSize0 = total_size / 2; | |
| int symbolSize1 = total_size - symbolSize0; | |
| int channel_half = symbolSize0 / per_channel_size; | |
| m_decoder0->decode_z(symbolSize0, cdf_group_index, start_offset, per_channel_size); | |
| m_decoder1->decode_z(symbolSize1, cdf_group_index, start_offset + channel_half, | |
| per_channel_size); | |
| } else { | |
| m_decoder0->decode_z(total_size, cdf_group_index, start_offset, per_channel_size); | |
| } | |
| } | |
| py::array_t<int8_t> RansDecoder::get_decoded_tensor() | |
| { | |
| if (m_use_two_decoders) { | |
| auto result0 = m_decoder0->get_decoded_tensor(); | |
| const int total_size0 = static_cast<int>(result0->size()); | |
| auto result1 = m_decoder1->get_decoded_tensor(); | |
| const int total_size1 = static_cast<int>(result1->size()); | |
| py::array_t<int8_t> output(total_size0 + total_size1); | |
| py::buffer_info buf = output.request(); | |
| int8_t* buf_ptr = static_cast<int8_t*>(buf.ptr); | |
| std::copy(result0->begin(), result0->end(), buf_ptr); | |
| std::copy(result1->begin(), result1->end(), buf_ptr + total_size0); | |
| return output; | |
| } | |
| auto result0 = m_decoder0->get_decoded_tensor(); | |
| const int total_size0 = static_cast<int>(result0->size()); | |
| py::array_t<int8_t> output(total_size0); | |
| py::buffer_info buf = output.request(); | |
| int8_t* buf_ptr = static_cast<int8_t*>(buf.ptr); | |
| std::copy(result0->begin(), result0->end(), buf_ptr); | |
| return output; | |
| } | |
| int RansDecoder::add_cdf(const py::array_t<int32_t>& cdfs, const py::array_t<int32_t>& cdfs_sizes, | |
| const py::array_t<int32_t>& offsets) | |
| { | |
| py::buffer_info cdfs_sizes_buf = cdfs_sizes.request(); | |
| py::buffer_info offsets_buf = offsets.request(); | |
| int32_t* cdfs_sizes_ptr = static_cast<int32_t*>(cdfs_sizes_buf.ptr); | |
| int32_t* offsets_ptr = static_cast<int32_t*>(offsets_buf.ptr); | |
| int cdf_num = static_cast<int>(cdfs_sizes.size()); | |
| auto vec_cdfs_sizes = std::make_shared<std::vector<int32_t>>(cdf_num); | |
| memcpy(vec_cdfs_sizes->data(), cdfs_sizes_ptr, sizeof(int32_t) * cdf_num); | |
| auto vec_offsets = std::make_shared<std::vector<int32_t>>(offsets.size()); | |
| memcpy(vec_offsets->data(), offsets_ptr, sizeof(int32_t) * offsets.size()); | |
| int per_vector_size = static_cast<int>(cdfs.size() / cdf_num); | |
| auto vec_cdfs = std::make_shared<std::vector<std::vector<int32_t>>>(cdf_num); | |
| auto cdfs_raw = cdfs.unchecked<2>(); | |
| for (int i = 0; i < cdf_num; i++) { | |
| std::vector<int32_t> t(per_vector_size); | |
| memcpy(t.data(), cdfs_raw.data(i, 0), sizeof(int32_t) * per_vector_size); | |
| vec_cdfs->at(i) = t; | |
| } | |
| int cdf_idx = m_decoder0->add_cdf(vec_cdfs, vec_cdfs_sizes, vec_offsets); | |
| m_decoder1->add_cdf(vec_cdfs, vec_cdfs_sizes, vec_offsets); | |
| return cdf_idx; | |
| } | |
| void RansDecoder::empty_cdf_buffer() | |
| { | |
| m_decoder0->empty_cdf_buffer(); | |
| m_decoder1->empty_cdf_buffer(); | |
| } | |
| void RansDecoder::set_use_two_decoders(bool b) | |
| { | |
| m_use_two_decoders = b; | |
| } | |
| bool RansDecoder::get_use_two_decoders() | |
| { | |
| return m_use_two_decoders; | |
| } | |
| std::vector<uint32_t> pmf_to_quantized_cdf(const std::vector<float>& pmf, int precision) | |
| { | |
| /* NOTE(begaintj): ported from `ryg_rans` public implementation. Not optimal | |
| * although it's only run once per model after training. See TF/compression | |
| * implementation for an optimized version. */ | |
| std::vector<uint32_t> cdf(pmf.size() + 1); | |
| cdf[0] = 0; /* freq 0 */ | |
| std::transform(pmf.begin(), pmf.end(), cdf.begin() + 1, [=](float p) { | |
| return static_cast<uint32_t>(std::round(p * (1 << precision)) + 0.5); | |
| }); | |
| const uint32_t total = std::accumulate(cdf.begin(), cdf.end(), 0); | |
| std::transform(cdf.begin(), cdf.end(), cdf.begin(), [precision, total](uint32_t p) { | |
| return static_cast<uint32_t>((((1ull << precision) * p) / total)); | |
| }); | |
| std::partial_sum(cdf.begin(), cdf.end(), cdf.begin()); | |
| cdf.back() = 1 << precision; | |
| for (int i = 0; i < static_cast<int>(cdf.size() - 1); ++i) { | |
| if (cdf[i] == cdf[i + 1]) { | |
| /* Try to steal frequency from low-frequency symbols */ | |
| uint32_t best_freq = ~0u; | |
| int best_steal = -1; | |
| for (int j = 0; j < static_cast<int>(cdf.size()) - 1; ++j) { | |
| uint32_t freq = cdf[j + 1] - cdf[j]; | |
| if (freq > 1 && freq < best_freq) { | |
| best_freq = freq; | |
| best_steal = j; | |
| } | |
| } | |
| assert(best_steal != -1); | |
| if (best_steal < i) { | |
| for (int j = best_steal + 1; j <= i; ++j) { | |
| cdf[j]--; | |
| } | |
| } else { | |
| assert(best_steal > i); | |
| for (int j = i + 1; j <= best_steal; ++j) { | |
| cdf[j]++; | |
| } | |
| } | |
| } | |
| } | |
| assert(cdf[0] == 0); | |
| assert(cdf.back() == (1u << precision)); | |
| for (int i = 0; i < static_cast<int>(cdf.size()) - 1; ++i) { | |
| assert(cdf[i + 1] > cdf[i]); | |
| } | |
| return cdf; | |
| } | |
| PYBIND11_MODULE(MLCodec_extensions_cpp, m) | |
| { | |
| py::class_<RansEncoder>(m, "RansEncoder") | |
| .def(py::init<>()) | |
| .def("encode_y", &RansEncoder::encode_y) | |
| .def("encode_z", &RansEncoder::encode_z) | |
| .def("flush", &RansEncoder::flush) | |
| .def("get_encoded_stream", &RansEncoder::get_encoded_stream) | |
| .def("reset", &RansEncoder::reset) | |
| .def("add_cdf", &RansEncoder::add_cdf) | |
| .def("empty_cdf_buffer", &RansEncoder::empty_cdf_buffer) | |
| .def("set_use_two_encoders", &RansEncoder::set_use_two_encoders) | |
| .def("get_use_two_encoders", &RansEncoder::get_use_two_encoders); | |
| py::class_<RansDecoder>(m, "RansDecoder") | |
| .def(py::init<>()) | |
| .def("set_stream", &RansDecoder::set_stream) | |
| .def("decode_y", &RansDecoder::decode_y) | |
| .def("decode_and_get_y", &RansDecoder::decode_and_get_y) | |
| .def("decode_z", &RansDecoder::decode_z) | |
| .def("get_decoded_tensor", &RansDecoder::get_decoded_tensor) | |
| .def("add_cdf", &RansDecoder::add_cdf) | |
| .def("empty_cdf_buffer", &RansDecoder::empty_cdf_buffer) | |
| .def("set_use_two_decoders", &RansDecoder::set_use_two_decoders) | |
| .def("get_use_two_decoders", &RansDecoder::get_use_two_decoders); | |
| m.def("pmf_to_quantized_cdf", &pmf_to_quantized_cdf, "Return quantized CDF for a given PMF"); | |
| } | |