Partilhar via


O que há de novo no ML.NET

Observação

Este artigo é um trabalho em andamento.

Você pode encontrar todas as notas de versão da API ML.NET no repositório dotnet/machinelearning.

Novas tarefas de aprendizagem profunda

ML.NET 3.0 adicionou suporte para as seguintes tarefas de aprendizagem profunda:

  • Deteção de objetos (apoiada por TorchSharp)
  • Reconhecimento de entidade nomeada (NER)
  • Resposta a perguntas (QA)

Esses instrutores estão incluídos no pacote Microsoft.ML.TorchSharp . Para obter mais informações, consulte Anunciando o ML.NET 3.0.

AutoML (Aprendizagem Automática Automatizada)

No ML.NET 3.0, o varredor AutoML foi atualizado para suportar as tarefas de semelhança de frases, resposta a perguntas e deteção de objetos. Para obter mais informações sobre AutoML, consulte Como usar a API ML.NET Automated Machine Learning (AutoML).

Suporte adicional ao tokenizador

A tokenização é um componente fundamental no pré-processamento de texto em linguagem natural para modelos de IA. Os tokenizadores são responsáveis por dividir uma cadeia de texto em partes menores e mais gerenciáveis, muitas vezes referidas como tokens. Ao usar serviços como o Azure OpenAI, você pode usar tokenizadores para obter uma melhor compreensão do custo e gerenciar o contexto. Ao trabalhar com modelos auto-hospedados ou locais, os tokens são as entradas fornecidas para esses modelos. Para obter mais informações sobre tokenização na biblioteca Microsoft.ML.Tokenizers, consulte Anunciando o ML.NET 2.0.

O pacote Microsoft.ML.Tokenizers fornece uma biblioteca de tokenização de código aberto entre plataformas. No ML.NET 4.0, a biblioteca foi melhorada das seguintes formas:

  • APIs refinadas e funcionalidades existentes.
  • Adicionado suporte Tiktoken.
  • Adicionado suporte de tokenizador para o Llama modelo.
  • Adicionado o CodeGen tokenizador, que é compatível com modelos como codegen-350M-mono e phi-2.
  • Foram adicionadas sobrecargas EncodeToIds que aceitam instâncias Span<char> e permitem a personalização da normalização e da pré-tokenização.
  • Trabalhei em estreita colaboração com as comunidades DeepDev TokenizerLib e SharpToken para abranger cenários contemplados por essas bibliotecas. Se você estiver usando DeepDev ou SharpToken, recomendamos migrar para Microsoft.ML.Tokenizerso . Para obter mais detalhes, consulte o guia de migração .

Os exemplos a seguir mostram como usar o tokenizador de Tiktoken texto.

Tokenizer tokenizer = TiktokenTokenizer.CreateForModel("gpt-4");
string text = "Hello, World!";

// Encode to IDs.
IReadOnlyList<int> encodedIds = tokenizer.EncodeToIds(text);
Console.WriteLine($"encodedIds = {{{string.Join(", ", encodedIds)}}}");
// encodedIds = {9906, 11, 4435, 0}

// Decode IDs to text.
string? decodedText = tokenizer.Decode(encodedIds);
Console.WriteLine($"decodedText = {decodedText}");
// decodedText = Hello, World!

// Get token count.
int idsCount = tokenizer.CountTokens(text);
Console.WriteLine($"idsCount = {idsCount}");
// idsCount = 4

// Full encoding.
IReadOnlyList<EncodedToken> result = tokenizer.EncodeToTokens(text, out string? normalizedString);
Console.WriteLine($"result.Tokens = {{'{string.Join("', '", result.Select(t => t.Value))}'}}");
// result.Tokens = {'Hello', ',', ' World', '!'}
Console.WriteLine($"result.Ids = {{{string.Join(", ", result.Select(t => t.Id))}}}");
// result.Ids = {9906, 11, 4435, 0}

// Encode up to number of tokens limit.
int index1 = tokenizer.GetIndexByTokenCount(
    text,
    maxTokenCount: 1,
    out string? processedText1,
    out int tokenCount1
    ); // Encode up to one token.
Console.WriteLine($"tokenCount1 = {tokenCount1}");
// tokenCount1 = 1
Console.WriteLine($"index1 = {index1}");
// index1 = 5

int index2 = tokenizer.GetIndexByTokenCountFromEnd(
    text,
    maxTokenCount: 1,
    out string? processedText2,
    out int tokenCount2
    ); // Encode from end up to one token.
Console.WriteLine($"tokenCount2 = {tokenCount2}");
// tokenCount2 = 1
Console.WriteLine($"index2 = {index2}");
// index2 = 12

Os exemplos a seguir mostram como usar o tokenizador de Llama texto.

// Create the Tokenizer.
string modelUrl = @"https://huggingface.co/hf-internal-testing/llama-llamaTokenizer/resolve/main/llamaTokenizer.model";
using Stream remoteStream = File.OpenRead(modelUrl);
Tokenizer llamaTokenizer = LlamaTokenizer.Create(remoteStream);

string text = "Hello, World!";

// Encode to IDs.
IReadOnlyList<int> encodedIds = llamaTokenizer.EncodeToIds(text);
Console.WriteLine($"encodedIds = {{{string.Join(", ", encodedIds)}}}");
// encodedIds = {1, 15043, 29892, 2787, 29991}

// Decode IDs to text.
string? decodedText = llamaTokenizer.Decode(encodedIds);
Console.WriteLine($"decodedText = {decodedText}");
// decodedText = Hello, World!

// Get token count.
int idsCount = llamaTokenizer.CountTokens(text);
Console.WriteLine($"idsCount = {idsCount}");
// idsCount = 5

// Full encoding.
IReadOnlyList<EncodedToken> result = llamaTokenizer.EncodeToTokens(text, out string? normalizedString);
Console.WriteLine($"result.Tokens = {{'{string.Join("', '", result.Select(t => t.Value))}'}}");
// result.Tokens = {'<s>', '▁Hello', ',', '▁World', '!'}
Console.WriteLine($"result.Ids = {{{string.Join(", ", result.Select(t => t.Id))}}}");
// result.Ids = {1, 15043, 29892, 2787, 29991}

// Encode up 2 tokens.
int index1 = llamaTokenizer.GetIndexByTokenCount(text, maxTokenCount: 2, out string? processedText1, out int tokenCount1);
Console.WriteLine($"tokenCount1 = {tokenCount1}");
// tokenCount1 = 2
Console.WriteLine($"index1 = {index1}");
// index1 = 6

// Encode from end up to one token.
int index2 = llamaTokenizer.GetIndexByTokenCountFromEnd(text, maxTokenCount: 1, out string? processedText2, out int tokenCount2);
Console.WriteLine($"tokenCount2 = {tokenCount2}");
// tokenCount2 = 1
Console.WriteLine($"index2 = {index2}");
// index2 = 13

Os exemplos a seguir mostram como usar o CodeGen tokenizador.

string phi2VocabPath = "https://huggingface.co/microsoft/phi-2/resolve/main/vocab.json?download=true";
string phi2MergePath = "https://huggingface.co/microsoft/phi-2/resolve/main/merges.txt?download=true";
using Stream vocabStream = File.OpenRead(phi2VocabPath);
using Stream mergesStream = File.OpenRead(phi2MergePath);

Tokenizer phi2Tokenizer = CodeGenTokenizer.Create(vocabStream, mergesStream);
IReadOnlyList<int> ids = phi2Tokenizer.EncodeToIds("Hello, World");

O exemplo a seguir demonstra como usar o tokenizador com Span<char> e como desabilitar a normalização ou pré-tokenização nas chamadas de codificação.

ReadOnlySpan<char> textSpan = "Hello World".AsSpan();

// Bypass normalization.
IReadOnlyList<int> ids = llamaTokenizer.EncodeToIds(textSpan, considerNormalization: false);

// Bypass pretokenization.
ids = llamaTokenizer.EncodeToIds(textSpan, considerPreTokenization: false);

Suporte em nível de byte no tokenizador BPE

O BpeTokenizer agora suporta codificação em nível de byte, permitindo a compatibilidade com modelos como o DeepSeek. Esta melhoria processa o vocabulário como UTF-8 bytes. Além disso, o novo BpeOptions tipo simplifica a configuração do tokenizador.

BpeOptions bpeOptions = new BpeOptions(vocabs);
BpeTokenizer tokenizer = BpeTokenizer.Create(bpeOptions);

Opção determinística para o instrutor LightGBM

Os treinadores LightGBM agora expõem opções para treinamento determinístico, garantindo resultados consistentes com os mesmos dados e sementes aleatórias. Essas opções incluem deterministic, force_row_wisee force_col_wise.

LightGbmBinaryTrainer trainer = ML.BinaryClassification.Trainers.LightGbm(new LightGbmBinaryTrainer.Options
{
    Deterministic = true,
    ForceRowWise = true
});

Construtor de modelos (extensão do Visual Studio)

O Construtor de Modelos foi atualizado para consumir a versão ML.NET 3.0. A versão 17.18.0 do Construtor de Modelos adicionou cenários de resposta a perguntas (QA) e de reconhecimento de entidade nomeada (NER).

Você pode encontrar todas as notas de versão do Model Builder no repositório dotnet/machinelearning-modelbuilder.

Ver também