Open weights are not always free to use
Open weights means the files of a model's numbers can be downloaded. It does not mean you may do anything you like with them. A licence sets the terms.
That matters because a company that builds on a model it may not use commercially can be told to stop. Reading the terms first costs ten minutes.
By the end of this lesson
Note
I can read a model's licence and say what it lets me do.
Key words
| Word | What it means |
|---|---|
| Weights | the learnt numbers of a model |
| Licence | the terms for using something |
| Clause | one rule inside a licence |
| Attribution | saying who made it |
| Use limit | a cap such as a number of users |
The cells students fill in are left blank in this preview.
A licence says what you may do
A model's weights have a licence, and the code that runs them may have another. Read both.
Each rule is a clause. Common clauses ask five things. Is commercial use allowed? Is there a use limit? Which purposes are banned? May you change the model, and must you share the changes? Must you give attribution?
Clauses to check, in plain words
| Clause | Question to ask |
|---|---|
| Commercial | May I earn money with it? |
| Use limit | Is there a cap, such as a number of users? |
| Banned uses | Is my purpose on the list? |
| Changes | May I change it, and must I share the change? |
| Attribution | Must I show who made it? |
The cells students fill in are left blank in this preview.
Test a use against every clause
Write down your use: is it commercial, how many users, what purpose, will you change the model and share the changes. Then test it against each clause in turn.
One failed clause is enough to say not allowed. If every clause passes but attribution is needed, the use is allowed with conditions.
A common mistake
Warning
Many people think a model on a public website is free for any use. Being easy to download says nothing about the terms. Read the clauses for your own use before you build on it. This lesson is practice, not legal advice.
Write the model helper, part 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// The token counts of a reply, or null when the reply carries none.' 'function count(data, name) {' ' return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > model.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the model helper, part 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function ask(messages, sample, max) {' ' try {' ' const res = await fetch(base + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"status \" + res.status);' ' const data = await res.json();' ' const text = data.choices[0].message.content;' ' return { text, inTokens: count(data, \"prompt_tokens\"), outTokens: count(data, \"completion_tokens\"), recorded: false };' ' } catch (error) {' ' console.log(\"Recorded sample: no model answered (\" + error.message + \").\");' ' return { text: sample, inTokens: null, outTokens: null, recorded: true };' ' }' '}' 'module.exports = { ask };' >> model.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the licence checker, part 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const licences = [' ' { name: \"Open A\", commercial: true, maxUsers: 1000, banned: [\"weapons\"], attribution: true, modify: true, share: false },' ' { name: \"Open B\", commercial: false, maxUsers: Infinity, banned: [], attribution: false, modify: true, share: true },' '];' 'const use = { commercial: true, users: 500, purpose: \"tutoring\", modifies: true, shares: false };' 'function problems(l, u) {' ' const found = [];' ' if (u.commercial && l.commercial === false) found.push(\"commercial use not allowed\");' ' if (u.users > l.maxUsers) found.push(\"over the user limit\");' > licence.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the licence checker, part 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' if (l.banned.includes(u.purpose)) found.push(\"banned use: \" + u.purpose);' ' if (u.modifies && l.modify === false) found.push(\"changes not allowed\");' ' if (u.modifies && l.share && u.shares === false) found.push(\"changes must be shared\");' ' return found;' '}' >> licence.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the licence checker, part 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function verdict(l, u) {' ' const found = problems(l, u);' ' if (found.length > 0) return \"not allowed\";' ' return l.attribution ? \"allowed with conditions\" : \"allowed\";' '}' >> licence.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Write the licence checker, part 4
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' console.log(\"use: commercial, 500 users, tutoring, modified, changes kept private\");' ' for (const l of licences) console.log(l.name + \": \" + verdict(l, use) + \" | \" + problems(l, use).join(\"; \"));' ' const q = \"In one short sentence, why should you read a model licence before using the weights?\";' ' const sample = \"The licence says what you may do with the weights, and breaking its terms can end your right to use them.\";' ' const reply = await ask([{ role: \"user\", content: q }], sample, 60);' ' console.log(\"model said: \" + reply.text);' '}' 'main();' >> licence.js"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Run the licence checker
docker exec -w /home/node/project agent node licence.jsShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
The licences here are invented
Open A and Open B are made up for practice. They are not real licences and say nothing about any real model.
The checker only does what you tell it to. A real licence needs a careful read, and a real doubt needs someone qualified.
What the Run prints
| Line | What it shows |
|---|---|
| Open A: allowed with conditions | | Every clause passes, but attribution is needed |
| Open B: not allowed | commercial use not allowed; changes must be shared | Two clauses fail |
| model said: ... | A sentence. The words differ each run |
The cells students fill in are left blank in this preview.