197 lines
6.2 KiB
Markdown
197 lines
6.2 KiB
Markdown
|
|
---
|
||
|
|
base_model: Qwen/Qwen2.5-0.5B-Instruct
|
||
|
|
library_name: transformers
|
||
|
|
model_name: qwen2.5-0.5b-game-commands-stt
|
||
|
|
tags:
|
||
|
|
- generated_from_trainer
|
||
|
|
- sft
|
||
|
|
- hf_jobs
|
||
|
|
- trl
|
||
|
|
- ml-intern
|
||
|
|
licence: license
|
||
|
|
---
|
||
|
|
|
||
|
|
# Model Card for qwen2.5-0.5b-game-commands-stt
|
||
|
|
|
||
|
|
This model is a fine-tuned version of [Qwen/Qwen2.5-0.5B-Instruct](https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct).
|
||
|
|
It has been trained using [TRL](https://github.com/huggingface/trl).
|
||
|
|
|
||
|
|
|
||
|
|
## Training procedure
|
||
|
|
|
||
|
|
This model was trained with SFT.
|
||
|
|
|
||
|
|
### Framework versions
|
||
|
|
|
||
|
|
- TRL: 1.3.0
|
||
|
|
- Transformers: 5.8.0
|
||
|
|
- Pytorch: 2.11.0
|
||
|
|
- Datasets: 4.8.5
|
||
|
|
- Tokenizers: 0.22.2
|
||
|
|
|
||
|
|
## Citations
|
||
|
|
|
||
|
|
Cite TRL as:
|
||
|
|
|
||
|
|
```bibtex
|
||
|
|
@software{vonwerra2020trl,
|
||
|
|
title = {{TRL: Transformers Reinforcement Learning}},
|
||
|
|
author = {von Werra, Leandro and Belkada, Younes and Tunstall, Lewis and Beeching, Edward and Thrush, Tristan and Lambert, Nathan and Huang, Shengyi and Rasul, Kashif and Gallouédec, Quentin},
|
||
|
|
license = {Apache-2.0},
|
||
|
|
url = {https://github.com/huggingface/trl},
|
||
|
|
year = {2020}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
If you use this model or approach in your work, please cite:
|
||
|
|
```bibtex
|
||
|
|
@misc{marco333_game_commands_2026,
|
||
|
|
author = {Marco333},
|
||
|
|
title = {Game Command Recognition from Noisy Speech-to-Text using Qwen2.5-0.5B},
|
||
|
|
year = {2026},
|
||
|
|
publisher = {Hugging Face},
|
||
|
|
url = {https://huggingface.co/Marco333/qwen2.5-0.5b-game-commands-stt},
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
```c++
|
||
|
|
|
||
|
|
#include "llama.h"
|
||
|
|
#include "common.h"
|
||
|
|
#include <string>
|
||
|
|
#include <iostream>
|
||
|
|
|
||
|
|
// System prompt - must match what the model was trained with
|
||
|
|
const char* SYSTEM_PROMPT =
|
||
|
|
"You are a game command interpreter. The user's input is noisy speech-to-text "
|
||
|
|
"from a microphone in a gaming environment. Your job is to identify the intended "
|
||
|
|
"game command from the noisy input.\n\n"
|
||
|
|
"Valid commands: Attack, CastSpell, CloseDoor, Crouch, Defend, DropItem, Heal, "
|
||
|
|
"Interact, Jump, OpenDoor, OpenInventory, OpenMap, PauseGame, PickUp, Reload, "
|
||
|
|
"SaveGame, Sprint, Stop, SwitchWeapon, UseItem\n\n"
|
||
|
|
"Respond with ONLY a JSON object: {\"command\": \"<CommandName>\"}\n"
|
||
|
|
"If the input doesn't match any command, respond: {\"command\": \"Unknown\"}";
|
||
|
|
|
||
|
|
// Build the prompt using Qwen2.5 chat template
|
||
|
|
std::string build_prompt(const std::string& stt_text) {
|
||
|
|
return "<|im_start|>system\n" + std::string(SYSTEM_PROMPT) + "<|im_end|>\n"
|
||
|
|
"<|im_start|>user\n" + stt_text + "<|im_end|>\n"
|
||
|
|
"<|im_start|>assistant\n";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Parse command from model output like: {"command": "OpenDoor"}
|
||
|
|
std::string parse_command(const std::string& output) {
|
||
|
|
auto pos = output.find("\"command\": \"");
|
||
|
|
if (pos == std::string::npos) pos = output.find("\"command\":\"");
|
||
|
|
if (pos == std::string::npos) return "Unknown";
|
||
|
|
|
||
|
|
pos = output.find("\"", pos + 11);
|
||
|
|
if (pos == std::string::npos) return "Unknown";
|
||
|
|
pos++;
|
||
|
|
|
||
|
|
auto end = output.find("\"", pos);
|
||
|
|
if (end == std::string::npos) return "Unknown";
|
||
|
|
|
||
|
|
return output.substr(pos, end - pos);
|
||
|
|
}
|
||
|
|
|
||
|
|
int main() {
|
||
|
|
// Initialize llama.cpp
|
||
|
|
llama_backend_init();
|
||
|
|
|
||
|
|
// Load model
|
||
|
|
llama_model_params model_params = llama_model_default_params();
|
||
|
|
llama_model* model = llama_model_load_from_file("model_q4.gguf", model_params);
|
||
|
|
|
||
|
|
// Create context
|
||
|
|
llama_context_params ctx_params = llama_context_default_params();
|
||
|
|
ctx_params.n_ctx = 512; // Short context is fine for commands
|
||
|
|
ctx_params.n_batch = 512;
|
||
|
|
llama_context* ctx = llama_init_from_model(model, ctx_params);
|
||
|
|
|
||
|
|
// Get the tokenizer/vocab from the model
|
||
|
|
const llama_vocab* vocab = llama_model_get_vocab(model);
|
||
|
|
|
||
|
|
// === GAME LOOP: process STT input ===
|
||
|
|
std::string stt_input = "opun da dur"; // Noisy STT from player mic
|
||
|
|
|
||
|
|
// Build prompt
|
||
|
|
std::string prompt = build_prompt(stt_input);
|
||
|
|
|
||
|
|
// Tokenize
|
||
|
|
std::vector<llama_token> tokens(512);
|
||
|
|
int n_tokens = llama_tokenize(vocab, prompt.c_str(), prompt.size(),
|
||
|
|
tokens.data(), tokens.size(), true, true);
|
||
|
|
tokens.resize(n_tokens);
|
||
|
|
|
||
|
|
// Create batch and evaluate prompt
|
||
|
|
llama_batch batch = llama_batch_init(512, 0, 1);
|
||
|
|
for (int i = 0; i < n_tokens; i++) {
|
||
|
|
llama_batch_add(batch, tokens[i], i, {0}, false);
|
||
|
|
}
|
||
|
|
batch.logits[batch.n_tokens - 1] = true;
|
||
|
|
llama_decode(ctx, batch);
|
||
|
|
|
||
|
|
// Generate response (max ~30 tokens for JSON output)
|
||
|
|
std::string response;
|
||
|
|
int n_cur = n_tokens;
|
||
|
|
|
||
|
|
for (int i = 0; i < 30; i++) {
|
||
|
|
llama_token new_token = llama_sampler_sample(/* your sampler */, ctx, -1);
|
||
|
|
|
||
|
|
// Stop at EOS or end of JSON
|
||
|
|
if (llama_vocab_is_eog(vocab, new_token)) break;
|
||
|
|
|
||
|
|
// Convert token to text
|
||
|
|
char buf[64];
|
||
|
|
int len = llama_token_to_piece(vocab, new_token, buf, sizeof(buf), 0, true);
|
||
|
|
response.append(buf, len);
|
||
|
|
|
||
|
|
// Stop if we see closing brace (JSON complete)
|
||
|
|
if (response.find("}") != std::string::npos) break;
|
||
|
|
|
||
|
|
// Prepare next token
|
||
|
|
llama_batch_clear(batch);
|
||
|
|
llama_batch_add(batch, new_token, n_cur, {0}, true);
|
||
|
|
llama_decode(ctx, batch);
|
||
|
|
n_cur++;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Parse the command
|
||
|
|
std::string command = parse_command(response);
|
||
|
|
std::cout << "STT: '" << stt_input << "' -> Command: " << command << std::endl;
|
||
|
|
// Output: STT: 'opun da dur' -> Command: OpenDoor
|
||
|
|
|
||
|
|
// Now trigger game action based on command string
|
||
|
|
// e.g. if (command == "OpenDoor") game->openNearestDoor();
|
||
|
|
|
||
|
|
// Cleanup
|
||
|
|
llama_batch_free(batch);
|
||
|
|
llama_free(ctx);
|
||
|
|
llama_model_free(model);
|
||
|
|
llama_backend_free();
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Usage
|
||
|
|
|
||
|
|
```python
|
||
|
|
from transformers import AutoModelForCausalLM, AutoTokenizer
|
||
|
|
|
||
|
|
model_id = 'Marco333/qwen2.5-0.5b-game-commands-stt'
|
||
|
|
tokenizer = AutoTokenizer.from_pretrained(model_id)
|
||
|
|
model = AutoModelForCausalLM.from_pretrained(model_id)
|
||
|
|
```
|
||
|
|
|
||
|
|
For non-causal architectures, replace `AutoModelForCausalLM` with the appropriate `AutoModel` class.
|
||
|
|
|
||
|
|
<!-- ml-intern-provenance -->
|
||
|
|
## Generated by ML Intern
|
||
|
|
|
||
|
|
This model repository was generated by [ML Intern](https://github.com/huggingface/ml-intern), an agent for machine learning research and development on the Hugging Face Hub.
|
||
|
|
|
||
|
|
- Try ML Intern: https://smolagents-ml-intern.hf.space
|
||
|
|
- Source code: https://github.com/huggingface/ml-intern
|