commit 00cad2d4b15db92eec4a95e1dabefea35d018e98 Author: ModelHub XC Date: Wed May 6 20:04:55 2026 +0800 初始化项目,由ModelHub XC社区提供模型 Model: nomeda-lab/Fattah-Orch-Small Source: Original Platform diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..30e921e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,38 @@ +*.7z filter=lfs diff=lfs merge=lfs -text +*.arrow filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.ckpt filter=lfs diff=lfs merge=lfs -text +*.ftz filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.h5 filter=lfs diff=lfs merge=lfs -text +*.joblib filter=lfs diff=lfs merge=lfs -text +*.lfs.* filter=lfs diff=lfs merge=lfs -text +*.mlmodel filter=lfs diff=lfs merge=lfs -text +*.model filter=lfs diff=lfs merge=lfs -text +*.msgpack filter=lfs diff=lfs merge=lfs -text +*.npy filter=lfs diff=lfs merge=lfs -text +*.npz filter=lfs diff=lfs merge=lfs -text +*.onnx filter=lfs diff=lfs merge=lfs -text +*.ot filter=lfs diff=lfs merge=lfs -text +*.parquet filter=lfs diff=lfs merge=lfs -text +*.pb filter=lfs diff=lfs merge=lfs -text +*.pickle filter=lfs diff=lfs merge=lfs -text +*.pkl filter=lfs diff=lfs merge=lfs -text +*.pt filter=lfs diff=lfs merge=lfs -text +*.pth filter=lfs diff=lfs merge=lfs -text +*.rar filter=lfs diff=lfs merge=lfs -text +*.safetensors filter=lfs diff=lfs merge=lfs -text +saved_model/**/* filter=lfs diff=lfs merge=lfs -text +*.tar.* filter=lfs diff=lfs merge=lfs -text +*.tar filter=lfs diff=lfs merge=lfs -text +*.tflite filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.wasm filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text +*tfevents* filter=lfs diff=lfs merge=lfs -text +tokenizer.json filter=lfs diff=lfs merge=lfs -text +logo.png filter=lfs diff=lfs merge=lfs -text +Gemini_Generated_Image_[[:space:]](4)-Photoroom.png filter=lfs diff=lfs merge=lfs -text diff --git a/README.md b/README.md new file mode 100644 index 0000000..17f0659 --- /dev/null +++ b/README.md @@ -0,0 +1,226 @@ +--- +tags: +- text-generation-inference +- transformers +- unsloth +license: apache-2.0 +language: +- en +--- +# Fattah-Orch — Arabic-First Coding Orchestrator + +**Fattah-Orch** is a lightweight model that sits at the top of your AI coding pipeline. Give it a software request in **Egyptian Arabic, Modern Standard Arabic, or English** — it thinks through the requirements and returns a clean, structured JSON task graph your coding agents can execute directly. + +

+ Fattah-Orch Logo +

+ + +## The Fattah-Orch Family + +| Model | Parameters | Target Device | +|---|---|---| +| [Fattah-Orch-XS](https://huggingface.co/nomeda-lab/Fattah-Orch-XS) | 0.6B | Any CPU | +| [Fattah-Orch-S](https://huggingface.co/nomeda-lab/Fattah-Orch-Small) | 1.7B | CPU / Weak GPU | +| [Fattah-Orch-M](https://huggingface.co/nomeda-lab/Fattah-Orch-M) | 4B | GPU / Apple Silicon | +| [Fattah-Orch-L](https://huggingface.co/nomeda-lab/Fattah-Orch-L) | 8B | Mid GPU 8GB+ | + +--- + +## What It Does + +``` +Your Request → Fattah-Orch → JSON Task Graph → Coder Model +(Arabic / English) (local, fast) (typed + ordered) (GPT-4o, Claude, etc.) +``` + +Instead of sending a vague prompt directly to an expensive coder model, Fattah-Orch breaks it down into precise, typed, dependency-ordered subtasks first. The coder model gets clear instructions — no back-and-forth, fewer tokens, better output. + +--- + +## Output Schema + +```json +{ + "request_summary": "Full sentence describing what was requested", + "subtasks": [ + { + "id": 1, + "title": "Short task name", + "description": "What to build and what it should do", + "type": "python", + "depends_on": [] + }, + { + "id": 2, + "title": "Another task", + "description": "What this builds and why it depends on task 1", + "type": "typescript", + "depends_on": [1] + } + ] +} +``` + +### Supported Task Types + +| Type | When used | +|---|---| +| `python` | Backend, APIs, scripts | +| `typescript` | Frontend, React, Next.js | +| `sql` | Database schema, migrations | +| `go` | High-performance backend services | +| `kotlin` | Android native | +| `swift` | iOS native | +| `bash` | Shell scripts, infrastructure | + +--- + +## Usage + +### Installation + +```bash +pip install unsloth transformers torch +``` + +### Inference + +```python +import json +import torch +from unsloth import FastLanguageModel + +MODEL_NAME = "nomeda-lab/Fattah-Orch-XS" # or -S, -M, -L + +SYSTEM_PROMPT = """You are Fattah-Orch, a software project orchestrator. + +RULES: +1. Always include BOTH backend AND frontend tasks when the request implies a full system +2. Each subtask description must be 1-2 sentences explaining WHAT to build and WHAT it should do +3. request_summary must be a full sentence describing the complete system requested +4. Output ONLY valid JSON, nothing else + +OUTPUT FORMAT: +{"request_summary": "...", "subtasks": [{"id": 1, "title": "...", "description": "...", "type": "python|typescript|sql|bash", "depends_on": []}]}""" + +model, tokenizer = FastLanguageModel.from_pretrained( + model_name=MODEL_NAME, + max_seq_length=2048, + dtype=None, + load_in_4bit=True, +) +FastLanguageModel.for_inference(model) + +def orchestrate(request: str) -> dict: + messages = [ + {"role": "system", "content": SYSTEM_PROMPT}, + {"role": "user", "content": request}, + ] + inputs = tokenizer.apply_chat_template( + messages, + tokenize=True, + add_generation_prompt=True, + return_tensors="pt", + enable_thinking=False, + ).to(model.device) + + with torch.no_grad(): + outputs = model.generate( + input_ids=inputs, + max_new_tokens=1024, + temperature=0.3, + top_p=0.9, + do_sample=True, + pad_token_id=tokenizer.eos_token_id, + ) + + response = tokenizer.decode( + outputs[0][inputs.shape[-1]:], + skip_special_tokens=True, + ) + return json.loads(response) + + +# Arabic +plan = orchestrate("عايز تطبيق e-commerce فيه products و cart و checkout") +print(json.dumps(plan, indent=2, ensure_ascii=False)) + +# English +plan = orchestrate("I want a REST API for a blog with posts, comments and auth") +print(json.dumps(plan, indent=2, ensure_ascii=False)) +``` + +--- + +## Example + +**Input:** `"عايز تطبيق e-commerce فيه products و cart و checkout"` + +```json +{ + "request_summary": "E-commerce application with product listing, shopping cart, and checkout flow", + "subtasks": [ + { + "id": 1, + "title": "Product database model", + "description": "Define Product model with name, price, stock, and category fields", + "type": "python", + "depends_on": [] + }, + { + "id": 2, + "title": "Products API", + "description": "Endpoints to list, create, update, and delete products", + "type": "python", + "depends_on": [1] + }, + { + "id": 3, + "title": "Cart and checkout API", + "description": "Endpoints to add items to cart, view cart, and process checkout with order creation", + "type": "python", + "depends_on": [2] + }, + { + "id": 4, + "title": "React storefront UI", + "description": "Product listing page, cart sidebar, and checkout form that consumes the backend API", + "type": "typescript", + "depends_on": [2] + } + ] +} +``` + +--- + +## Limitations + +- Best performance on Egyptian Arabic colloquial. MSA and other dialects work but may be less fluent. +- Task description quality improves with model size — XS is a fast baseline, L produces richer output. +- For very large systems (microservices, monorepos) prefer Orch-M or Orch-L. +- This model plans tasks — it does not write code. Connect it to a coder model for full end-to-end generation. + +--- + +## Citation + +```bibtex +@model{fattah_orch_2026, + title = {Fattah-Orch Family: Arabic-First Coding Orchestrator Models}, + author = {Nomeda Lab}, + year = {2026}, + url = {https://huggingface.co/collections/nomeda-lab/fattah-orch-family} +} +``` + +--- + +## License + +[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/) — free for research and internal use; commercial redistribution requires permission. + +--- + +*Part of the **Fattah project** — an open Arabic-first AI coding assistant ecosystem built at Nomeda Lab.* \ No newline at end of file diff --git a/chat_template.jinja b/chat_template.jinja new file mode 100644 index 0000000..642e597 --- /dev/null +++ b/chat_template.jinja @@ -0,0 +1,53 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0]['role'] == 'system' %} + {{- messages[0]['content'] }} + {%- else %} + {{- 'You are Qwen, created by Alibaba Cloud. You are a helpful assistant.' }} + {%- endif %} + {{- "\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0]['role'] == 'system' %} + {{- '<|im_start|>system\n' + messages[0]['content'] + '<|im_end|>\n' }} + {%- else %} + {{- '<|im_start|>system\nYou are Qwen, created by Alibaba Cloud. You are a helpful assistant.<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- for message in messages %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) or (message.role == "assistant" and not message.tool_calls) %} + {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {{- '<|im_start|>' + message.role }} + {%- if message.content %} + {{- '\n' + message.content }} + {%- endif %} + {%- for tool_call in message.tool_calls %} + {%- if tool_call.function is defined %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {{- tool_call.arguments | tojson }} + {{- '}\n' }} + {%- endfor %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if (loop.index0 == 0) or (messages[loop.index0 - 1].role != "tool") %} {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- message.content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} +{%- endif %} diff --git a/config.json b/config.json new file mode 100644 index 0000000..7a5afdd --- /dev/null +++ b/config.json @@ -0,0 +1,64 @@ +{ + "architectures": [ + "Qwen3ForCausalLM" + ], + "attention_bias": false, + "attention_dropout": 0.0, + "bos_token_id": null, + "torch_dtype": "float16", + "eos_token_id": 151645, + "head_dim": 128, + "hidden_act": "silu", + "hidden_size": 2048, + "initializer_range": 0.02, + "intermediate_size": 6144, + "layer_types": [ + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention" + ], + "max_position_embeddings": 40960, + "max_window_layers": 28, + "model_type": "qwen3", + "num_attention_heads": 16, + "num_hidden_layers": 28, + "num_key_value_heads": 8, + "pad_token_id": 151669, + "rms_norm_eps": 1e-06, + "rope_parameters": { + "rope_theta": 1000000, + "rope_type": "default" + }, + "sliding_window": null, + "tie_word_embeddings": true, + "unsloth_fixed": true, + "unsloth_version": "2026.4.8", + "use_cache": false, + "use_sliding_window": false, + "vocab_size": 151936 +} \ No newline at end of file diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..0f64257 --- /dev/null +++ b/logo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6bf95911e48b11ce286ceb6bbde74702ba5d744bc8e7fd06d9fb632fc8a706b0 +size 420877 diff --git a/model.safetensors b/model.safetensors new file mode 100644 index 0000000..3ede9fe --- /dev/null +++ b/model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc770f087e43251cc9a8f073d14a7cfc61e9da70a324b9a4f41e342ede9b5b54 +size 3441185608 diff --git a/tokenizer.json b/tokenizer.json new file mode 100644 index 0000000..7edcf72 --- /dev/null +++ b/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7430e9138b76e93fb6f93462394d236b411111aef53cb421ba97d2691040cca +size 11423114 diff --git a/tokenizer_config.json b/tokenizer_config.json new file mode 100644 index 0000000..c53f397 --- /dev/null +++ b/tokenizer_config.json @@ -0,0 +1,234 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "is_local": false, + "model_max_length": 40960, + "pad_token": "<|PAD_TOKEN|>", + "padding_side": "left", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null, + "added_tokens_decoder": { + "151643": { + "content": "<|endoftext|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151644": { + "content": "<|im_start|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151645": { + "content": "<|im_end|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151646": { + "content": "<|object_ref_start|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151647": { + "content": "<|object_ref_end|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151648": { + "content": "<|box_start|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151649": { + "content": "<|box_end|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151650": { + "content": "<|quad_start|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151651": { + "content": "<|quad_end|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151652": { + "content": "<|vision_start|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151653": { + "content": "<|vision_end|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151654": { + "content": "<|vision_pad|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151655": { + "content": "<|image_pad|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151656": { + "content": "<|video_pad|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + }, + "151657": { + "content": "", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": false + }, + "151658": { + "content": "", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": false + }, + "151659": { + "content": "<|fim_prefix|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": false + }, + "151660": { + "content": "<|fim_middle|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": false + }, + "151661": { + "content": "<|fim_suffix|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": false + }, + "151662": { + "content": "<|fim_pad|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": false + }, + "151663": { + "content": "<|repo_name|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": false + }, + "151664": { + "content": "<|file_sep|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": false + }, + "151665": { + "content": "", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": false + }, + "151666": { + "content": "", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": false + }, + "151667": { + "content": "", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": false + }, + "151668": { + "content": "", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": false + }, + "151669": { + "content": "<|PAD_TOKEN|>", + "single_word": false, + "lstrip": false, + "rstrip": false, + "normalized": false, + "special": true + } + }, + "chat_template": "{%- if tools %}\n {{- '<|im_start|>system\\n' }}\n {%- if messages[0]['role'] == 'system' %}\n {{- messages[0]['content'] }}\n {%- else %}\n {{- 'You are Qwen, created by Alibaba Cloud. You are a helpful assistant.' }}\n {%- endif %}\n {{- \"\\n\\n# Tools\\n\\nYou may call one or more functions to assist with the user query.\\n\\nYou are provided with function signatures within XML tags:\\n\" }}\n {%- for tool in tools %}\n {{- \"\\n\" }}\n {{- tool | tojson }}\n {%- endfor %}\n {{- \"\\n\\n\\nFor each function call, return a json object with function name and arguments within XML tags:\\n\\n{\\\"name\\\": , \\\"arguments\\\": }\\n<|im_end|>\\n\" }}\n{%- else %}\n {%- if messages[0]['role'] == 'system' %}\n {{- '<|im_start|>system\\n' + messages[0]['content'] + '<|im_end|>\\n' }}\n {%- else %}\n {{- '<|im_start|>system\\nYou are Qwen, created by Alibaba Cloud. You are a helpful assistant.<|im_end|>\\n' }}\n {%- endif %}\n{%- endif %}\n{%- for message in messages %}\n {%- if (message.role == \"user\") or (message.role == \"system\" and not loop.first) or (message.role == \"assistant\" and not message.tool_calls) %}\n {{- '<|im_start|>' + message.role + '\\n' + message.content + '<|im_end|>' + '\\n' }}\n {%- elif message.role == \"assistant\" %}\n {{- '<|im_start|>' + message.role }}\n {%- if message.content %}\n {{- '\\n' + message.content }}\n {%- endif %}\n {%- for tool_call in message.tool_calls %}\n {%- if tool_call.function is defined %}\n {%- set tool_call = tool_call.function %}\n {%- endif %}\n {{- '\\n\\n{\"name\": \"' }}\n {{- tool_call.name }}\n {{- '\", \"arguments\": ' }}\n {{- tool_call.arguments | tojson }}\n {{- '}\\n' }}\n {%- endfor %}\n {{- '<|im_end|>\\n' }}\n {%- elif message.role == \"tool\" %}\n {%- if (loop.index0 == 0) or (messages[loop.index0 - 1].role != \"tool\") %} {{- '<|im_start|>user' }}\n {%- endif %}\n {{- '\\n\\n' }}\n {{- message.content }}\n {{- '\\n' }}\n {%- if loop.last or (messages[loop.index0 + 1].role != \"tool\") %}\n {{- '<|im_end|>\\n' }}\n {%- endif %}\n {%- endif %}\n{%- endfor %}\n{%- if add_generation_prompt %}\n {{- '<|im_start|>assistant\\n' }}\n{%- endif %}\n" +} \ No newline at end of file