Tutorial: Creación de un modelo de inquilino (versión preliminar)
Tenant Model (Habla personalizada con datos de Microsoft 365 ) es un servicio opcional para clientes empresariales de Microsoft 365 que genera automáticamente un modelo de reconocimiento de voz personalizado a partir de los datos de Microsoft 365 de su organización. El modelo está optimizado para términos técnicos, jerga y nombres de personas, y todo ello de forma segura y compatible.
Importante
Si su organización se inscribe mediante el servicio Tenant Model, el servicio de voz puede acceder al modelo de lenguaje de su organización. El modelo se genera a partir de documentos y correos electrónicos de grupos públicos de Microsoft 365, que puede ver cualquier usuario de la organización. El administrador de su organización puede activar o desactivar el uso del modelo de lenguaje en toda la organización desde el portal de administración.
En este tutorial, aprenderá a:
- Inscribirse en Tenant Model desde el Centro de administración de Microsoft 365
- Obtener una clave de suscripción del servicio Voz
- Crear un modelo de inquilino
- Implementar un modelo de inquilino
- Usar un modelo de inquilino con el SDK de Voz
Inscripción en el servicio Tenant Model
Para poder implementar un modelo de inquilino, es preciso estar inscrito en el servicio Tenant Model. La inscripción se completa en el centro de administración de Microsoft 365 y solo puede realizarla el administrador.
Inicie sesión en el Centro de administración de Microsoft 365.
En el panel izquierdo, seleccione Configuración, de nuevo Configuración en el menú anidado y, finalmente, seleccione Servicios de voz de Azure en la ventana principal.

Seleccione la casilla Permitir el modelo de idioma de toda la organización y, después, Guardar cambios.

Para desactivar la instancia del modelo de inquilino:
- Repita los pasos 1 y 2 anteriores.
- Desactive la casilla Permitir el modelo de idioma de toda la organización y seleccione Guardar cambios.
Obtener una clave de suscripción del servicio Voz
Para usar un modelo de inquilino con el SDK de Voz, necesita un recurso de Voz y su clave de suscripción asociada.
Inicie sesión en Azure Portal.
Seleccione Crear un recurso.
En el cuadro Buscar en Marketplace, escriba Speech.
En la lista de resultados, seleccione Speech y, después, Crear.
Siga las instrucciones en pantalla para crear el recurso. Asegúrese de lo siguiente:
- La ubicación se ha establecido en eastus o westus.
- El plan de tarifa está establecido en S0.
Seleccione Crear.
Después de unos minutos, se crea el recurso. La clave de suscripción está disponible en la sección Información general del recurso.
Creación de un modelo de lenguaje
Una vez que el administrador haya habilitado el servicio Tenant Model para su organización, puede crear un modelo de lenguaje basado en sus datos de Microsoft 365.
Inicie sesión en Speech Studio.
En la parte superior derecha, seleccione Settings (Configuración) (icono del engranaje) y, después, Tenant Model settings (Configuración de Tenant Model).

Speech Studio muestra un mensaje que le indica que si es apto para crear un modelo de inquilino.
Nota
Los clientes empresariales de Norteamérica pueden crear un modelo de inquilino (inglés). Para los clientes de Caja de seguridad del cliente, Clave de cliente u Office 365 Administración Pública característica no está disponible. Para determinar si es un cliente de Caja de seguridad del cliente o de Clave de cliente, consulte:
Seleccione Habilitar envío.
Cuando el modelo de inquilino esté listo, recibirá un mensaje de correo electrónico de confirmación con más instrucciones.
Implementación de un modelo de inquilino
Cuando la instancia del modelo de inquilino esté lista, siga estos pasos para implementarla:
En el mensaje de correo electrónico de confirmación, seleccione el botón View model (Ver modelo). O bien, inicie sesión en Speech Studio.
En la parte superior derecha, seleccione Settings (Configuración) (icono del engranaje) y, después, Tenant Model settings (Configuración de Tenant Model).

Seleccione Implementar.
Cuando el modelo se haya implementado, el estado cambiará a Implementado.
Usar un modelo de inquilino con el SDK de Voz
Ahora que ha implementado el modelo, puede usarlo con el SDK de Voz. En esta sección, se usa un código de ejemplo para llamar al servicio de voz mediante la autenticación de Azure Active Directory (Azure AD).
Echemos un vistazo al código que usará para llamar al SDK de Voz en C#. En este ejemplo, el reconocimiento de voz se realiza mediante un modelo de inquilino. En esta guía se da por supuesto que la plataforma ya está configurada. Si necesita ayuda para el programa de configuración, consulte Inicio rápido: Reconocimiento de voz, C# (.NET Core).
Copie este código en el proyecto:
namespace PrincetonSROnly.FrontEnd.Samples
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Newtonsoft.Json.Linq;
// ServiceApplicationId is a fixed value. No need to change it.
public class TenantLMSample
{
private const string EndpointUriArgName = "EndpointUri";
private const string SubscriptionKeyArgName = "SubscriptionKey";
private const string UsernameArgName = "Username";
private const string PasswordArgName = "Password";
private const string ClientApplicationId = "f87bc118-1576-4097-93c9-dbf8f45ef0dd";
private const string ServiceApplicationId = "18301695-f99d-4cae-9618-6901d4bdc7be";
public static async Task ContinuousRecognitionWithTenantLMAsync(Uri endpointUri, string subscriptionKey, string audioDirPath, string username, string password)
{
var config = SpeechConfig.FromEndpoint(endpointUri, subscriptionKey);
// Passing client specific information for obtaining LM
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
config.AuthorizationToken = await AcquireAuthTokenWithInteractiveLoginAsync().ConfigureAwait(false);
}
else
{
config.AuthorizationToken = await AcquireAuthTokenWithUsernamePasswordAsync(username, password).ConfigureAwait(false);
}
var stopRecognition = new TaskCompletionSource<int>();
// Creates a speech recognizer using file as audio input.
// Replace with your own audio file name.
using (var audioInput = AudioConfig.FromWavFileInput(audioDirPath))
{
using (var recognizer = new SpeechRecognizer(config, audioInput))
{
// Subscribes to events
recognizer.Recognizing += (s, e) =>
{
Console.WriteLine($"RECOGNIZING: Text={e.Result.Text}");
};
recognizer.Recognized += (s, e) =>
{
if (e.Result.Reason == ResultReason.RecognizedSpeech)
{
Console.WriteLine($"RECOGNIZED: Text={e.Result.Text}");
}
else if (e.Result.Reason == ResultReason.NoMatch)
{
Console.WriteLine($"NOMATCH: Speech could not be recognized.");
}
};
recognizer.Canceled += (s, e) =>
{
Console.WriteLine($"CANCELED: Reason={e.Reason}");
if (e.Reason == CancellationReason.Error)
{
Exception exp = new Exception(string.Format("Error Code: {0}\nError Details{1}\nIs your subscription information updated?", e.ErrorCode, e.ErrorDetails));
throw exp;
}
stopRecognition.TrySetResult(0);
};
recognizer.SessionStarted += (s, e) =>
{
Console.WriteLine("\n Session started event.");
};
recognizer.SessionStopped += (s, e) =>
{
Console.WriteLine("\n Session stopped event.");
Console.WriteLine("\nStop recognition.");
stopRecognition.TrySetResult(0);
};
// Starts continuous recognition. Uses StopContinuousRecognitionAsync() to stop recognition.
await recognizer.StartContinuousRecognitionAsync().ConfigureAwait(false);
// Waits for completion.
// Use Task.WaitAny to keep the task rooted.
Task.WaitAny(new[] { stopRecognition.Task });
// Stops recognition.
await recognizer.StopContinuousRecognitionAsync().ConfigureAwait(false);
}
}
}
public static void Main(string[] args)
{
var arguments = new Dictionary<string, string>();
string inputArgNamePattern = "--";
Regex regex = new Regex(inputArgNamePattern);
if (args.Length > 0)
{
foreach (var arg in args)
{
var userArgs = arg.Split("=");
arguments[regex.Replace(userArgs[0], string.Empty)] = userArgs[1];
}
}
var endpointString = arguments.GetValueOrDefault(EndpointUriArgName, $"wss://westus.online.princeton.customspeech.ai/msgraphcustomspeech/conversation/v1");
var endpointUri = new Uri(endpointString);
if (!arguments.ContainsKey(SubscriptionKeyArgName))
{
Exception exp = new Exception("Subscription Key missing! Please pass in a Cognitive services subscription Key using --SubscriptionKey=\"your_subscription_key\"" +
"Find more information on creating a Cognitive services resource and accessing your Subscription key here: https://docs.microsoft.com/azure/cognitive-services/cognitive-services-apis-create-account?tabs=multiservice%2Cwindows");
throw exp;
}
var subscriptionKey = arguments[SubscriptionKeyArgName];
var username = arguments.GetValueOrDefault(UsernameArgName, null);
var password = arguments.GetValueOrDefault(PasswordArgName, null);
var audioDirPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "../../../AudioSamples/DictationBatman.wav");
if (!File.Exists(audioDirPath))
{
Exception exp = new Exception(string.Format("Audio File does not exist at path: {0}", audioDirPath));
throw exp;
}
ContinuousRecognitionWithTenantLMAsync(endpointUri, subscriptionKey, audioDirPath, username, password).GetAwaiter().GetResult();
}
private static async Task<string> AcquireAuthTokenWithUsernamePasswordAsync(string username, string password)
{
var tokenEndpoint = "https://login.microsoftonline.com/common/oauth2/token";
var postBody = $"resource={ServiceApplicationId}&client_id={ClientApplicationId}&grant_type=password&username={username}&password={password}";
var stringContent = new StringContent(postBody, Encoding.UTF8, "application/x-www-form-urlencoded");
using (HttpClient httpClient = new HttpClient())
{
var response = await httpClient.PostAsync(tokenEndpoint, stringContent).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
JObject jobject = JObject.Parse(result);
return jobject["access_token"].Value<string>();
}
else
{
throw new Exception($"Requesting token from {tokenEndpoint} failed with status code {response.StatusCode}: {await response.Content.ReadAsStringAsync().ConfigureAwait(false)}");
}
}
}
private static async Task<string> AcquireAuthTokenWithInteractiveLoginAsync()
{
var authContext = new AuthenticationContext("https://login.windows.net/microsoft.onmicrosoft.com");
var deviceCodeResult = await authContext.AcquireDeviceCodeAsync(ServiceApplicationId, ClientApplicationId).ConfigureAwait(false);
Console.WriteLine(deviceCodeResult.Message);
var authResult = await authContext.AcquireTokenByDeviceCodeAsync(deviceCodeResult).ConfigureAwait(false);
return authResult.AccessToken;
}
}
}
Después tendrá que volver a compilar y ejecutar el proyecto desde la línea de comandos. Antes de ejecutar el comando, actualice algunos parámetros, para lo que debe seguir estos pasos:
Reemplace
<Username>y<Password>por los valores de un usuario de inquilino válido.Reemplace
<Subscription-Key>por la clave de suscripción del recurso de Voz. Este valor está disponible en la hoja de información general del recurso de Voz de Azure Portal.Reemplace
<Endpoint-Uri>por el siguiente punto de conexión. Asegúrese de que reemplaza{your region}por la región donde se creó el recurso de Voz. Se admiten estas regiones:westus,westus2yeastus. La información de la región está disponible en la sección de información general del recurso de Voz de Azure Portal."wss://{your region}.online.princeton.customspeech.ai/msgraphcustomspeech/conversation/v1".Ejecute el siguiente comando:
dotnet TenantLMSample.dll --Username=<Username> --Password=<Password> --SubscriptionKey=<Subscription-Key> --EndpointUri=<Endpoint-Uri>
En este tutorial, ha aprendido a usar los datos de Microsoft 365 para crear un modelo de reconocimiento de voz personalizado, implementarlo y usarlo con el SDK de voz.