Solution
import heapq
import numpy as np
class BeamSearch:
def __init__(self, model, beam_width=3, max_length=10):
self.model = model # Probability function or language model
self.beam_width = beam_width
self.max_length = max_length
def search(self, start_token):
"""Performs beam search to find the best sequence."""
# Priority queue to store sequences with probabilities
sequences = [(0.0, [start_token])] # (log_probability, sequence)
for _ in range(self.max_length):
all_candidates = []
# Expand each sequence
for log_prob, seq in sequences:
if seq[-1] == "": # Stop if end token is reached
all_candidates.append((log_prob, seq))
continue
# Get next token probabilities (simulated model output)
next_tokens = self.model(seq)
# Add beam_width candidates
for token, prob in next_tokens:
new_seq = seq + [token]
new_log_prob = log_prob + np.log(prob) # Use log probability to avoid underflow
all_candidates.append((new_log_prob, new_seq))
# Keep the top-k sequences with highest probability
sequences = heapq.nlargest(self.beam_width, all_candidates, key=lambda x: x[0])
# Return the sequence with the highest probability
return sequences[0][1]
# Example Model (Simulated)
def dummy_model(sequence):
"""Simulates a model that predicts next token probabilities."""
vocab = ["hello", "world", ""]
probs = np.random.dirichlet(np.ones(len(vocab))) # Random probabilities
return list(zip(vocab, probs))
# Example usage
beam_search = BeamSearch(dummy_model, beam_width=3, max_length=5)
best_sequence = beam_search.search(start_token="")
print("Best Sequence:", best_sequence)