Granite 3.0 es una familia liviana y de código abierto de modelos de lenguaje generativo diseñados para una variedad de tareas de nivel empresarial. Admite de forma nativa funcionalidad, codificación, razonamiento y uso de herramientas en varios idiomas, lo que lo hace adecuado para entornos empresariales.
Probé la ejecución de este modelo para ver qué tareas puede realizar.
Configuré el entorno Granite 3.0 en Google Colab e instalé las bibliotecas necesarias usando los siguientes comandos:
!pip install torch torchvision torchaudio !pip install accelerate !pip install -U transformers
Probé el rendimiento de los modelos 2B y 8B de Granite 3.0.
Ejecuté el modelo 2B. Aquí está el ejemplo de código para el modelo 2B:
import torch from transformers import AutoModelForCausalLM, AutoTokenizer device = "auto" model_path = "ibm-granite/granite-3.0-2b-instruct" tokenizer = AutoTokenizer.from_pretrained(model_path) model = AutoModelForCausalLM.from_pretrained(model_path, device_map=device) model.eval() chat = [ { "role": "user", "content": "Please list one IBM Research laboratory located in the United States. You should only output its name and location." }, ] chat = tokenizer.apply_chat_template(chat, tokenize=False, add_generation_prompt=True) input_tokens = tokenizer(chat, return_tensors="pt").to("cuda") output = model.generate(**input_tokens, max_new_tokens=100) output = tokenizer.batch_decode(output) print(output[0])
userPlease list one IBM Research laboratory located in the United States. You should only output its name and location. assistant1. IBM Research - Austin, Texas
El modelo 8B se puede utilizar reemplazando 2b por 8b. Aquí hay un ejemplo de código sin campos de entrada de rol ni de usuario para el modelo 8B:
import torch from transformers import AutoModelForCausalLM, AutoTokenizer device = "auto" model_path = "ibm-granite/granite-3.0-8b-instruct" tokenizer = AutoTokenizer.from_pretrained(model_path) model = AutoModelForCausalLM.from_pretrained(model_path, device_map=device) model.eval() chat = [ { "content": "Please list one IBM Research laboratory located in the United States. You should only output its name and location." }, ] chat = tokenizer.apply_chat_template(chat, tokenize=False, add_generation_prompt=True) input_tokens = tokenizer(chat, add_special_tokens=False, return_tensors="pt").to("cuda") output = model.generate(**input_tokens, max_new_tokens=100) generated_text = tokenizer.decode(output[0][input_tokens["input_ids"].shape[1]:], skip_special_tokens=True) print(generated_text)
1. IBM Almaden Research Center - San Jose, California
Exploré la función Llamada a función y la probé con una función ficticia. Aquí, get_current_weather está definido para devolver datos meteorológicos simulados.
import json def get_current_weather(location: str) -> dict: """ Retrieves current weather information for the specified location (default: San Francisco). Args: location (str): Name of the city to retrieve weather data for. Returns: dict: Dictionary containing weather information (temperature, description, humidity). """ print(f"Getting current weather for {location}") try: weather_description = "sample" temperature = "20.0" humidity = "80.0" return { "description": weather_description, "temperature": temperature, "humidity": humidity } except Exception as e: print(f"Error fetching weather data: {e}") return {"weather": "NA"}
Creé un mensaje para llamar a la función:
functions = [ { "name": "get_current_weather", "description": "Get the current weather", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city and country code, e.g. San Francisco, US", } }, "required": ["location"], }, }, ] query = "What's the weather like in Boston?" payload = { "functions_str": [json.dumps(x) for x in functions] } chat = [ {"role":"system","content": f"You are a helpful assistant with access to the following function calls. Your task is to produce a sequence of function calls necessary to generate response to the user utterance. Use the following function calls as required.{payload}"}, {"role": "user", "content": query } ]
Usando el siguiente código, generé una respuesta:
instruction_1 = tokenizer.apply_chat_template(chat, tokenize=False, add_generation_prompt=True) input_tokens = tokenizer(instruction_1, return_tensors="pt").to("cuda") output = model.generate(**input_tokens, max_new_tokens=1024) generated_text = tokenizer.decode(output[0][input_tokens["input_ids"].shape[1]:], skip_special_tokens=True) print(generated_text)
{'name': 'get_current_weather', 'arguments': {'location': 'Boston'}}
Esto confirmó la capacidad del modelo para generar la llamada de función correcta según la ciudad especificada.
Granite 3.0 permite la especificación de formato para facilitar las respuestas en formatos estructurados. Esta sección explica el uso de [DECLARACIÓN] para respuestas y [PENSAR] para pensamientos internos.
Por otro lado, dado que las llamadas a funciones se generan como texto sin formato, puede ser necesario implementar un mecanismo separado para distinguir entre llamadas a funciones y respuestas de texto normales.
Aquí hay un ejemplo de indicación para guiar la salida de la IA:
prompt = """You are a conversational AI assistant that deepens interactions by alternating between responses and inner thoughts.* Record spoken responses after the [UTTERANCE] tag and inner thoughts after the [THINK] tag. * Use [UTTERANCE] as a start marker to begin outputting an utterance. * After [THINK], describe your internal reasoning or strategy for the next response. This may include insights on the user's reaction, adjustments to improve interaction, or further goals to deepen the conversation. * Important: **Use [UTTERANCE] and [THINK] as a start signal without needing a closing tag.** Follow these instructions, alternating between [UTTERANCE] and [THINK] formats for responses. example> Please respond to the following user_input.Hello! What can you do? """
el código para generar una respuesta:
chat = [ { "role": "user", "content": prompt }, ] chat = tokenizer.apply_chat_template(chat, tokenize=False, add_generation_prompt=True) input_tokens = tokenizer(chat, return_tensors="pt").to("cuda") output = model.generate(**input_tokens, max_new_tokens=1024) generated_text = tokenizer.decode(output[0][input_tokens["input_ids"].shape[1]:], skip_special_tokens=True) print(generated_text)
El resultado es el siguiente:
[UTTERANCE]Hello! I'm here to provide information, answer questions, and assist with various tasks. I can help with a wide range of topics, from general knowledge to specific queries. How can I assist you today? [THINK]I've introduced my capabilities and offered assistance, setting the stage for the user to share their needs or ask questions.
Las etiquetas [UTTERANCE] y [THINK] se utilizaron correctamente, lo que permitió dar formato a la respuesta de manera eficaz.
Dependiendo del mensaje, a veces pueden aparecer etiquetas de cierre (como [/UTTERANCE] o [/THINK]) en la salida, pero en general, el formato de salida generalmente se puede especificar correctamente.
Veamos también cómo generar respuestas en streaming.
El siguiente código utiliza las bibliotecas asyncio y threading para transmitir de forma asincrónica respuestas desde Granite 3.0.
import asyncio from threading import Thread from typing import AsyncIterator from transformers import ( AutoTokenizer, AutoModelForCausalLM, TextIteratorStreamer, ) device = "auto" model_path = "ibm-granite/granite-3.0-8b-instruct" tokenizer = AutoTokenizer.from_pretrained(model_path) model = AutoModelForCausalLM.from_pretrained(model_path, device_map=device) model.eval() async def generate(chat) -> AsyncIterator[str]: # Apply chat template and tokenize input chat = tokenizer.apply_chat_template(chat, tokenize=False, add_generation_prompt=True) input_tokens = tokenizer(chat, add_special_tokens=False, return_tensors="pt").to("cuda") # Set up the streamer streamer = TextIteratorStreamer( tokenizer, skip_prompt=True, skip_special_tokens=True, ) generation_kwargs = dict( **input_tokens, streamer=streamer, max_new_tokens=1024, ) # Generate response in a separate thread thread = Thread(target=model.generate, kwargs=generation_kwargs) thread.start() for output in streamer: if not output: continue await asyncio.sleep(0) yield output # Execute asynchronous generation in the main function async def main(): chat = [ { "role": "user", "content": "Please list one IBM Research laboratory located in the United States. You should only output its name and location." }, ] generator = generate(chat) async for output in generator: # Use async for to retrieve responses sequentially print(output, end="|") await main()
La ejecución del código anterior generará respuestas asincrónicas en el siguiente formato:
1. |IBM |Almaden |Research |Center |- |San |Jose, |California|
Este ejemplo demuestra una transmisión exitosa. Cada token se genera de forma asincrónica y se muestra secuencialmente, lo que permite a los usuarios ver el proceso de generación en tiempo real.
Granite 3.0 proporciona respuestas razonablemente sólidas incluso con el modelo 8B. Las funciones de llamada de función y especificación de formato también funcionan bastante bien, lo que indica su potencial para una amplia gama de aplicaciones.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3