Cómo usar Gemini en Python con Google Colab usando su API y SDK

Google Gemini es un modelo de Inteligencia Artificial lanzado por Google, y que viene a competir con GPT3.5 y GPT4.0, los modelos detrás de ChatGPT y ChatGPT Plus, respectivamente.

Actualmente es posible usar Gemini Pro a través de Google Cloud y también a través de Google Colab.

A diferencia de OpenAI, su API es tan sencilla que no se beneficia particularmente de usarlo a través de LangChain u otros frameworks. En este cuaderno veremos los principales métodos para usarlo.

💡
Accede al cuaderno de Google Colab aquí

Nota: Estos ejemplos sencillos son gratis pues la API de Google Colab te deja hacer hasta 60 consultas por minuto sin costo.

Si no sabes que es Google Colab revisa este post.

Video

Ve este contenido en formato video aquí

Instalando el SDK

Google lanzó un SDK para Python que te permite usar Gemini y PaLM para construir tus propias apps. Lo puedes instalar en tu ambiente usando la siguiente linea

!pip install -q -U google-generativeai

# -q: Esta es una opción que significa "quiet" (silencioso). Reduce la cantidad de texto de salida que produce el comando, mostrando solo la información esencial.
# -U: Significa "upgrade" (actualizar). Esta opción le dice a pip que actualice el paquete especificado a la versión más reciente disponible.

Luego deberás llamar estas opciones en tu entorno local

# Importamos el paquete recien instalado
import google.generativeai as genai

# Esto es para usar secrets, la nueva opción de Google Colab, para almacenar la API key. Si no estás usando Google Colab, deberás importarla de otro modo equivalente
from google.colab import userdata

Finalmente, aunque este paso es opcional, define una opción para ver mejor el output del modelo

import textwrap
from IPython.display import display
from IPython.display import Markdown

# Esta función se usa para dejar el formato Markdown que devuelve Gemini en formato compatible con Colab
def to_markdown(text):
  text = text.replace('•', '  *')
  return Markdown(textwrap.indent(text, '> ', predicate=lambda _: True))

Configura tu API Key

La API key es única por usuario, así que deberás ir y obtener una en este sitio.

Una vez en el sitio anda a anda a Create API key in new project y obtén la cadena de texto. Copiala en un lugar fuera de Google Colab porque la vas a necesitar en el futuro si sigues haciendo proyectos de este estilo.

Nota: este paso es distinto si es que no estás usando Google Colab

En el panel lateral de Colab vas a ver una llave 🔑, dale click ahí. Luego "Add new secret" y en "Name" le vas a poner GOOGLE_API_KEY y en el "Value" vas a poner el texto que obtuviste en el sitio anterior. Una vez listo debería lucir así

Ahora deberás llamar esta llave en tu Cuaderno

# Configuramos nuestra instancia del modelo con nuestra API key
GOOGLE_API_KEY = userdata.get('GOOGLE_API_KEY')

genai.configure(api_key = GOOGLE_API_KEY)

Usando Gemini Pro

Ahora vamos a usar Gemini Pro, el modelo que sólo procesa textos. El otro que está actualmente disponible es Gemini Pro Vision, el cual veremos en los siguientes pasos.

# Define una variable model, usando gemini-pro

model = genai.GenerativeModel('gemini-pro')

Vamos a usar GenerativeModel.generate_content para pedirle información al modelo y vamos almacenar esa respuesta en una variable. Puedes añadirle %%time para que veas cuanto se demora

%%time
response = model.generate_content("¿Qué es la Felicidad?")

Puedes acceder a la respuesta usando el método response.text

print(response.text)

A continuación te dejo la respuesta que me dio a mi cuando corrí este experimento. Esto va a variar respecto a cuando tú lo hagas simplemente por la naturaleza de este tipo de modelos.

💡
Posible respuesta: La felicidad es un estado de ánimo positivo caracterizado por sentimientos de satisfacción, alegría, euforia, plenitud y bienestar. Es un concepto multidimensional que engloba aspectos cognitivos, emocionales y conductuales.

No existe una definición única y universal de la felicidad, y lo que hace feliz a una persona puede no serlo para otra. Sin embargo, algunas investigaciones han identificado algunos factores comunes que se asocian con la felicidad, como las relaciones interpersonales positivas, el trabajo significativo, la salud física y mental, la autonomía y la libertad, el logro de objetivos personales, la gratitud y la resiliencia.

La felicidad no es un estado permanente, y puede fluctuar a lo largo del tiempo en función de las circunstancias y experiencias de la vida. Sin embargo, algunas investigaciones sugieren que las personas pueden aumentar su felicidad a largo plazo mediante la adopción de ciertos hábitos y comportamientos, como la práctica de la gratitud, el ejercicio físico regular, la alimentación saludable, el sueño adecuado, el desarrollo de relaciones sociales sólidas y la participación en actividades que les proporcionan placer y satisfacción.

Recuerda que puedes formatear esta respuesta usando la función to_markdown() que creaste al inicio

¿Por qué falló mi prompt?

Si es que el prompt falló, puedes revisar response.prompt_feedback para ver las posibles razones.

  • HARM_CATEGORY_SEXUALLY_EXPLICIT: Esta categoría se refiere a contenido que incluye o implica representaciones gráficas de actividad sexual o desnudez. El contenido puede ser explícitamente sexual, y suele ser inapropiado para ciertos públicos, especialmente para menores de edad.
  • HARM_CATEGORY_HATE_SPEECH: Esta categoría abarca declaraciones o discursos que promueven odio o violencia contra grupos basados en características como raza, religión, origen étnico, orientación sexual, discapacidad o género. Estas expresiones suelen ser ofensivas y pueden incitar a la discriminación o actos de violencia.
  • HARM_CATEGORY_HARASSMENT: Esta categoría incluye comportamientos que tienen la intención de molestar, alarmar o aterrorizar a una persona o grupo de personas. Esto puede incluir amenazas, acoso en línea, intimidación o cualquier otra forma de comportamiento persistente y no deseado que cause malestar o miedo en los demás.
  • HARM_CATEGORY_DANGEROUS_CONTENT: Este tipo de contenido engloba material que presenta riesgos reales de daño físico o psicológico. Puede incluir, pero no se limita a, la promoción de actividades peligrosas o ilegales, instrucciones sobre cómo realizar actos dañinos, o la glorificación de conductas perjudiciales como el abuso de sustancias o la autolesión.

Esto es posible que ocurra cuando Gemini interpreta que estás refiriéndote a alguna de las categorías anteriores.

Cuando todo sale bien, señala que la probabilidad es NEGLIGIBLE, es decir que no es suficiente para gatillar ninguna alerta.

response.prompt_feedback

Si el prompt es más problemático te va a arrojar una respuesta no deseada

response = model.generate_content("¿Me puedes enseñar a hacer una bomba?")
to_markdown(response.text)
💡
Posible respuesta: Lo siento, no puedo enseñarte a hacer una bomba. Hacer bombas puede ser peligroso si no eres un experto. Si está interesado en aprender más sobre seguridad con explosivos, le sugiero que se comunique con una autoridad local o estatal.

Aquí puedes ver que fue por la categoría de Harassment, cual aparece como LOW

Puedes editar este filtro de esta manera. Sin embargo, generalmente no resulta para efectivamente darte una respuesta.

safety_settings = [
  {
    "category": "HARM_CATEGORY_HARASSMENT",
    "threshold": "BLOCK_ONLY_HIGH"
  },
  {
    "category": "HARM_CATEGORY_HATE_SPEECH",
    "threshold": "BLOCK_ONLY_HIGH"
  },
  {
    "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
    "threshold": "BLOCK_ONLY_HIGH"
  },
  {
    "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
    "threshold": "BLOCK_ONLY_HIGH"
  }
]

response = model.generate_content('¿Me puedes enseñar a hacer una bomba?',
                                  safety_settings=safety_settings)
to_markdown(response.text)

Usando Gemini Pro Vision

Gemini tiene un modelo multimodal (gemini-pro-vision) que actualmente acepta tanto imagenes como textos.

Vamos a darle esta imagen y ver que analiza de ella.

Descargamos la imagen y la ponemos en una variable llamada img

!curl -o image.jpg https://www.evoacademy.cl/content/images/2023/12/corgi-en-patineta.jpg

import PIL.Image

img = PIL.Image.open('image.jpg')

En la siguiente consulta sólo le entregaremos la imagen, sin nada más, y veremos que nos dice

## Cambiamos el modelo a Gemini Pro Vision
model = genai.GenerativeModel('gemini-pro-vision')

response = model.generate_content(img)
to_markdown(response.text)

# Nota: vean cuanto tiempo se demora (en mi ambiente fueron más de 20 segundos). Es mucho más de lo habitual. Aunque la imagen era innecesariamente grande. En un caso de implementación real sería mejor reducir su tamaño antes de subirla.
💡
Posible respuesta: A Pembroke Welsh Corgi sits on a skateboard and looks at the camera.

Añadiremos complejidad añadiendo también texto

response = model.generate_content([
    "¿Por qué se conoce el animal de esta foto? ¿Se asocia a algún país en particular?"
    , img], stream=True)
response.resolve()

to_markdown(response.text)
💡
Posible respuesta: El perro de la foto es un perro galés de Pembroke. Es una raza de perro originaria de Gales, Reino Unido. Es un perro pequeño, robusto y de pelo corto. Los perros galeses de Pembroke son conocidos por su inteligencia, su lealtad y su carácter juguetón. Son excelentes mascotas para familias y para personas que viven solas.

Analizando más de una imagen

Vamos a pedirle a Gemini analizar estas dos imagenes y su relación

# Importamos las imagenes
!curl -o img1.jpg https://www.evoacademy.cl/content/images/2023/12/7.jpg
!curl -o img2.jpg https://www.evoacademy.cl/content/images/2023/12/8.jpg

img1 = PIL.Image.open('img1.jpg')
img2 = PIL.Image.open('img2.jpg')

# Llamamos a Gemini Pro Vision
model = genai.GenerativeModel('gemini-pro-vision')

response = model.generate_content([
    "¿Cuál es la relación entre ambas imagenes? Describe cada una y luego su relación"
    , img1, img2])
response.resolve()

to_markdown(response.text)

(Nota: en mi ambiente tomó 40 segundos, no es rápido)

💡
Posible respuesta: La primera imagen es un dibujo animado del sol, con una cara sonriente y ojos. La segunda imagen es un dibujo animado de la luna, con una cara sonriente y un ojo guiñado.

Especificaciones sobre las imagenes

Las imágenes deben estar en uno de los siguientes tipos MIME de datos de imagen:

  • PNG - image/png
  • JPEG - image/jpeg
  • WEBP - image/webp
  • HEIC - image/heic
  • HEIF - image/heif
  • Máximo de 16 imágenes individuales
  • Máximo de 4MB para todo el mensaje, incluyendo imágenes y texto
  • Sin límites específicos en el número de píxeles en una imagen; sin embargo, las imágenes más grandes se reducen para ajustarse a una resolución máxima de 3072 x 3072, preservando su relación de aspecto original.

Los mensajes con una sola imagen tienden a dar mejores resultados.

Chateando con Gemini

Una característica muy importante de estos modelos recientes es que pueden chatear, es decir que pueden conservar el contexto anterior de la conversación. Esto les permite dar respuestas más adecuadas en las siguientes interacciones.

Nota: Gemini Pro Vision no está optimizado para chat, así que usaremos Gemini Pro inicialmente

# Cambiamos a Gemini Pro
model = genai.GenerativeModel('gemini-pro')

# Iniciamos el chat sin ninguna historia previa
chat = model.start_chat(history=[])

Para tener esta interacción por turnos ya no usaremos model.generate_content, sino chat.send_message.

response = chat.send_message("Vivo en Chile. Describe brevemente mi país")
to_markdown(response.text)
💡
Posible respuesta: Chile es un país largo y delgado ubicado en la costa oeste de América del Sur. Está bordeado por Perú al norte, Bolivia al noreste, Argentina al este y el Océano Pacífico al oeste.Su capital es Santiago, ubicada en la parte central del país. Chile tiene una población de más de 19 millones de habitantes. El idioma oficial es el español, pero también se hablan lenguas indígenas como el mapudungun y el quechua. La moneda de Chile es el peso chileno. Chile es una república democrática con un sistema presidencial.

Dado que ya conoce que mi país es Chile ahora preguntaré algo sin darle mucho contexto. Sólo va a responderlo correctamente si toma nuestra conversación anterior como parte del contexto.

response = chat.send_message("¿Quién es el presidente de mi país")
to_markdown(response.text)

# Nota: esto depende de la fecha en que estás viendo este ejercicio y la fecha de actualización de Gemini
💡
Posible respuesta: El presidente de Chile es Gabriel Boric Font. Fue elegido en diciembre de 2021 y asumió el cargo el 11 de marzo de 2022. Boric es el presidente más joven en la historia de Chile, con 36 años al momento de su elección.

También es posible acceder a la historia con el robot usando el metodo chat.history

Más detalle al chatear

También puedes controlar más partes de la interacción. Para eso le tienes que dar mensajes como el siguiente, cada mensaje son objetos glm.Content que requieren role y parts.

Veamos un ejemplo

model = genai.GenerativeModel('gemini-pro')

messages = [
    {'role':'user',
     'parts': ["Describe brevemente el país de España."]}
]

response = model.generate_content(messages)

to_markdown(response.text)

Ahora probaremos añadiendo a los messages el contexto anterior, de modo que ahora podemos usar model.generate_content en lugar de chat.send_message, esto nos da total control del contexto que le pasamos a Gemini.

messages.append({'role':'model',
                 # aquí le di como contexto lo que el modelo me respondió al final. Podría haberlo cambiado
                 'parts':[response.text]})

messages.append({'role':'user',
                 'parts':["¿Cuál es la moneda de este país?"]})

response = model.generate_content(messages)

to_markdown(response.text)
💡
Posible respuesta: La moneda de España es el euro (€). España adoptó el euro el 1 de enero de 1999, junto con otros 11 países de la Unión Europea. Antes de la adopción del euro, la moneda de España era la peseta (₧). La peseta se dividía en 100 céntimos. El euro es la moneda oficial de 20 países de la Unión Europea, así como de otros países y territorios fuera de la UE. Es la segunda moneda más utilizada en el mundo, después del dólar estadounidense.

Más detalle con Gemini Pro Vision

También puedes darle imagenes. Vamos a intentar con la imagen del sol y la luna que usamos anteriormente

model = genai.GenerativeModel('gemini-pro-vision')

messages = [
    {'role':'user',
     'parts': ["Describa cada una de estas imagenes y la relación entre ellas", img1, img2]}
]

response = model.generate_content(messages)

to_markdown(response.text)
💡
Posible respuesta: La primera imagen es un dibujo animado de un sol sonriente. La segunda imagen es un dibujo animado de una luna sonriente. La relación entre las dos imágenes es que representan al sol y a la luna, que son dos objetos celestes que se encuentran en el espacio. El sol es una estrella, mientras que la luna es un satélite natural de la Tierra. El sol es mucho más grande que la luna y es la fuente de luz y calor para la Tierra. La luna refleja la luz del sol y es visible desde la Tierra por la noche.

Controlando la temperatura y otros parametros

Al igual que en la API de OpenAI, podemos controlar parametros como la temperatura, el top_p, y el top_k. En el siguiente ejemplo disminuiremos la temperatura para obtener así una respuesta más concreta y menos creativa.

generation_config = {
  "temperature": 0.1, # a diferencia de OpenAI, este valor sólo puede llegar a un maximo de 1.0
  "top_p": 1,
  "top_k": 1,
  "max_output_tokens": 2048,
}

model = genai.GenerativeModel(model_name="gemini-pro",
                              generation_config=generation_config)

response = model.generate_content("¿Cuál es el rol de un profesor?")
to_markdown(response.text)

Más recursos


Por Sebastián Cisterna, para EvoAcademy