Current section

Files

Jump to
crucible_datasets lib dataset_manager loader no_robots.ex
Raw

lib/dataset_manager/loader/no_robots.ex

defmodule CrucibleDatasets.Loader.NoRobots do
@moduledoc """
NoRobots instruction-following dataset loader.
NoRobots contains human-written instruction-response pairs
for training instruction-following models. The dataset includes
high-quality examples across various categories like coding,
summarization, creative writing, and more.
Source: https://huggingface.co/datasets/HuggingFaceH4/no_robots
## Categories
The dataset covers these instruction categories:
- Open QA: General question answering
- Generation: Text generation tasks
- Brainstorm: Creative ideation
- Rewrite: Text transformation
- Summarize: Summarization tasks
- Classify: Classification tasks
- Closed QA: Factual question answering
- Extract: Information extraction
- Chat: Conversational responses
## Examples
# Load with defaults
{:ok, dataset} = NoRobots.load()
# Load with sample size
{:ok, dataset} = NoRobots.load(sample_size: 100)
# Load specific split
{:ok, dataset} = NoRobots.load(split: :train)
"""
alias CrucibleDatasets.Dataset
@categories [
"Open QA",
"Generation",
"Brainstorm",
"Rewrite",
"Summarize",
"Classify",
"Closed QA",
"Extract",
"Chat"
]
@doc """
Load NoRobots dataset.
For demo purposes, generates synthetic data.
In production, would fetch from HuggingFace.
## Options
* `:split` - Dataset split (:train, :test) default: :train
* `:sample_size` - Limit items (default: 50)
* `:seed` - Random seed for reproducibility
"""
@spec load(keyword()) :: {:ok, Dataset.t()}
def load(opts \\ []) do
# In production, this would fetch from HuggingFace:
# https://huggingface.co/datasets/HuggingFaceH4/no_robots
# For now, generate synthetic data for testing
items = generate_sample_items(opts)
dataset =
Dataset.new(
"no_robots",
"1.0",
items,
%{
source: "huggingface:HuggingFaceH4/no_robots",
license: "Apache-2.0",
domain: "instruction_following"
}
)
{:ok, dataset}
end
# Generate sample NoRobots items for testing
defp generate_sample_items(opts) do
count = Keyword.get(opts, :sample_size, 50)
# Use a deterministic seed for consistent checksums across loads
seed = Keyword.get(opts, :seed, 12_345)
:rand.seed(:exsss, {seed, seed, seed})
instruction_templates = [
{"Write a short poem about %topic%.", "Here is a short poem about %topic%:\n\n%content%"},
{"Summarize the following text: %topic%",
"Here is a summary:\n\n%topic% can be condensed to its key points which are %content%."},
{"Explain %topic% in simple terms.",
"Let me explain %topic% simply:\n\n%content% This makes it easier to understand."},
{"What are the main benefits of %topic%?",
"The main benefits of %topic% include:\n\n1. %content%\n2. Improved efficiency\n3. Better outcomes"},
{"Generate a list of ideas for %topic%.",
"Here are some ideas for %topic%:\n\n- %content%\n- Try a new approach\n- Consider alternatives"},
{"Rewrite this in a more formal tone: %topic%",
"In a more formal register:\n\n%content% This represents the key aspects of %topic%."},
{"What is %topic%?", "%topic% is %content%. It is commonly used in various applications."},
{"Create a brief outline for %topic%.",
"Outline for %topic%:\n\nI. Introduction\nII. %content%\nIII. Conclusion"},
{"How can I improve my %topic%?",
"To improve your %topic%, consider:\n\n1. %content%\n2. Practice regularly\n3. Seek feedback"},
{"Classify the following: %topic%",
"Classification: %topic% belongs to the category of %content%."}
]
topics = [
"machine learning",
"climate change",
"healthy eating",
"time management",
"software development",
"creative writing",
"public speaking",
"financial planning",
"meditation",
"team collaboration"
]
content_snippets = [
"effective strategies and techniques",
"fundamental concepts and principles",
"best practices for success",
"key considerations and factors",
"important aspects to consider"
]
all_items =
Enum.map(1..count, fn i ->
{instruction_template, response_template} = Enum.random(instruction_templates)
topic = Enum.random(topics)
content = Enum.random(content_snippets)
category = Enum.random(@categories)
instruction =
instruction_template
|> String.replace("%topic%", topic)
response =
response_template
|> String.replace("%topic%", topic)
|> String.replace("%content%", content)
%{
id: "no_robots_#{i}",
input: instruction,
expected: response,
metadata: %{
category: category,
topic: topic
}
}
end)
# Shuffle with seeded random, then take the requested count
all_items
|> Enum.shuffle()
|> Enum.take(count)
end
@doc """
Parse NoRobots JSONL format (if loading from file).
Expected format:
{"prompt": "...", "completion": "...", "category": "..."}
"""
@spec parse_jsonl(String.t()) :: [map()]
def parse_jsonl(content) do
content
|> String.split("\n", trim: true)
|> Enum.with_index()
|> Enum.map(fn {line, idx} ->
case Jason.decode(line) do
{:ok, item} ->
%{
id: "no_robots_#{idx}",
input: item["prompt"] || item["instruction"] || "",
expected: item["completion"] || item["response"] || item["output"] || "",
metadata: %{
category: item["category"] || "unknown"
}
}
_ ->
nil
end
end)
|> Enum.reject(&is_nil/1)
end
end